| Previous | 199869 Revisions | Next |
| r34388 Tuesday 13th January, 2015 at 14:40:48 UTC by RealComboman |
|---|
| added output so artwork can display current gear settings |
| [/trunk] | makefile |
| [3rdparty/lsqlite3] | lsqlite3.c |
| [3rdparty/lua] | Makefile README |
| [3rdparty/lua/doc] | contents.html lua.1 lua.css manual.html readme.html |
| [3rdparty/lua/src] | Makefile lapi.c lapi.h lauxlib.c lauxlib.h lbaselib.c lbitlib.c lcode.c lcode.h lcorolib.c lctype.c lctype.h ldblib.c ldebug.c ldebug.h ldo.c ldo.h ldump.c lfunc.c lfunc.h lgc.c lgc.h linit.c liolib.c llex.c llex.h llimits.h lmathlib.c lmem.c lmem.h loadlib.c lobject.c lobject.h lopcodes.c lopcodes.h loslib.c lparser.c lparser.h |
| [src/emu] | clifront.c clifront.h |
| [src/emu/bus/nes] | ggenie.c ggenie.h nes_slot.h |
| [src/emu/imagedev] | floppy.c |
| [src/emu/sound] | qs1000.c |
| [src/emu/ui] | filemngr.c |
| [src/lib] | lib.mak |
| [src/mame/drivers] | dec0.c sprint2.c |
| [src/mame/includes] | dec0.h |
| [src/mame/machine] | dec0.c |
| [src/mame/video] | dec0.c decbac06.c |
| [src/osd] | osdepend.c* osdepend.h |
| [src/osd/modules/lib] | osdobj_common.c osdobj_common.h |
| [src/osd/sdl] | osdsdl.h sdlmain.c |
| [src/osd/windows] | winmain.c winmain.h winprefix.h |
| r242899 | r242900 | |
|---|---|---|
| 476 | 476 | static int dbvm_bind_index(lua_State *L, sqlite3_stmt *vm, int index, int lindex) { |
| 477 | 477 | switch (lua_type(L, lindex)) { |
| 478 | 478 | case LUA_TSTRING: |
| 479 | return sqlite3_bind_text(vm, index, lua_tostring(L, lindex), lua_r | |
| 479 | return sqlite3_bind_text(vm, index, lua_tostring(L, lindex), lua_strlen(L, lindex), SQLITE_TRANSIENT); | |
| 480 | 480 | case LUA_TNUMBER: |
| 481 | 481 | return sqlite3_bind_double(vm, index, lua_tonumber(L, lindex)); |
| 482 | 482 | case LUA_TBOOLEAN: |
| r242899 | r242900 | |
| 522 | 522 | sdb_vm *svm = lsqlite_checkvm(L, 1); |
| 523 | 523 | int index = luaL_checkint(L, 2); |
| 524 | 524 | const char *value = luaL_checkstring(L, 3); |
| 525 | int len = lua_r | |
| 525 | int len = lua_strlen(L, 3); | |
| 526 | 526 | |
| 527 | 527 | lua_pushnumber(L, sqlite3_bind_blob(svm->vm, index, value, len, SQLITE_TRANSIENT)); |
| 528 | 528 | return 1; |
| r242899 | r242900 | |
| 797 | 797 | sqlite3_result_double(ctx->ctx, luaL_checknumber(L, 2)); |
| 798 | 798 | break; |
| 799 | 799 | case LUA_TSTRING: |
| 800 | sqlite3_result_text(ctx->ctx, luaL_checkstring(L, 2), lua_r | |
| 800 | sqlite3_result_text(ctx->ctx, luaL_checkstring(L, 2), lua_strlen(L, 2), SQLITE_TRANSIENT); | |
| 801 | 801 | break; |
| 802 | 802 | case LUA_TNIL: |
| 803 | 803 | case LUA_TNONE: |
| r242899 | r242900 | |
| 814 | 814 | static int lcontext_result_blob(lua_State *L) { |
| 815 | 815 | lcontext *ctx = lsqlite_checkcontext(L, 1); |
| 816 | 816 | const char *blob = luaL_checkstring(L, 2); |
| 817 | int size = lua_r | |
| 817 | int size = lua_strlen(L, 2); | |
| 818 | 818 | sqlite3_result_blob(ctx->ctx, (const void*)blob, size, SQLITE_TRANSIENT); |
| 819 | 819 | return 0; |
| 820 | 820 | } |
| r242899 | r242900 | |
| 829 | 829 | static int lcontext_result_error(lua_State *L) { |
| 830 | 830 | lcontext *ctx = lsqlite_checkcontext(L, 1); |
| 831 | 831 | const char *err = luaL_checkstring(L, 2); |
| 832 | int size = lua_r | |
| 832 | int size = lua_strlen(L, 2); | |
| 833 | 833 | sqlite3_result_error(ctx->ctx, err, size); |
| 834 | 834 | return 0; |
| 835 | 835 | } |
| r242899 | r242900 | |
| 850 | 850 | static int lcontext_result_text(lua_State *L) { |
| 851 | 851 | lcontext *ctx = lsqlite_checkcontext(L, 1); |
| 852 | 852 | const char *text = luaL_checkstring(L, 2); |
| 853 | int size = lua_r | |
| 853 | int size = lua_strlen(L, 2); | |
| 854 | 854 | sqlite3_result_text(ctx->ctx, text, size, SQLITE_TRANSIENT); |
| 855 | 855 | return 0; |
| 856 | 856 | } |
| r242899 | r242900 | |
| 1001 | 1001 | |
| 1002 | 1002 | if (lua_pcall(L, argc + 1, 0, 0)) { |
| 1003 | 1003 | const char *errmsg = lua_tostring(L, -1); |
| 1004 | int size = lua_r | |
| 1004 | int size = lua_strlen(L, -1); | |
| 1005 | 1005 | sqlite3_result_error(context, errmsg, size); |
| 1006 | 1006 | } |
| 1007 | 1007 | |
| r242899 | r242900 | |
| 1658 | 1658 | static int db_prepare(lua_State *L) { |
| 1659 | 1659 | sdb *db = lsqlite_checkdb(L, 1); |
| 1660 | 1660 | const char *sql = luaL_checkstring(L, 2); |
| 1661 | int sql_len = lua_r | |
| 1661 | int sql_len = lua_strlen(L, 2); | |
| 1662 | 1662 | const char *sqltail; |
| 1663 | 1663 | sdb_vm *svm; |
| 1664 | 1664 | lua_settop(L,2); /* sql is on top of stack for call to newvm */ |
| r242899 | r242900 | |
|---|---|---|
| 36 | 36 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= |
| 37 | 37 | |
| 38 | 38 | # Convenience platforms targets. |
| 39 | PLATS= aix bsd | |
| 39 | PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris | |
| 40 | 40 | |
| 41 | 41 | # What to install. |
| 42 | 42 | TO_BIN= lua luac |
| r242899 | r242900 | |
| 45 | 45 | TO_MAN= lua.1 luac.1 |
| 46 | 46 | |
| 47 | 47 | # Lua version and release. |
| 48 | V= 5.3 | |
| 49 | R= $V.0 | |
| 48 | V= 5.2 | |
| 49 | R= $V.3 | |
| 50 | 50 | |
| 51 | 51 | # Targets start here. |
| 52 | 52 | all: $(PLAT) |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | |
| 2 | This is Lua 5. | |
| 2 | This is Lua 5.2.3, released on 11 Nov 2013. | |
| 3 | 3 | |
| 4 | 4 | For installation instructions, license details, and |
| 5 | 5 | further information about Lua, see doc/readme.html. |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| 2 | 2 | <HTML> |
| 3 | 3 | <HEAD> |
| 4 | <TITLE>Lua 5. | |
| 4 | <TITLE>Lua 5.2 Reference Manual - contents</TITLE> | |
| 5 | 5 | <LINK REL="stylesheet" TYPE="text/css" HREF="lua.css"> |
| 6 | 6 | <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1"> |
| 7 | 7 | <STYLE TYPE="text/css"> |
| r242899 | r242900 | |
| 17 | 17 | <HR> |
| 18 | 18 | <H1> |
| 19 | 19 | <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="" BORDER=0></A> |
| 20 | Lua 5. | |
| 20 | Lua 5.2 Reference Manual | |
| 21 | 21 | </H1> |
| 22 | 22 | |
| 23 | 23 | <P> |
| r242899 | r242900 | |
| 33 | 33 | <A HREF="#index">index</A> |
| 34 | 34 | <HR> |
| 35 | 35 | <SMALL> |
| 36 | Copyright © 201 | |
| 36 | Copyright © 2011–2013 Lua.org, PUC-Rio. | |
| 37 | 37 | Freely available under the terms of the |
| 38 | 38 | <A HREF="http://www.lua.org/license.html">Lua license</A>. |
| 39 | 39 | </SMALL> |
| r242899 | r242900 | |
| 73 | 73 | <LI><A HREF="manual.html#3.4">3.4 – Expressions</A> |
| 74 | 74 | <UL> |
| 75 | 75 | <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 – Bitwise Operators</A> | |
| 77 | <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 – Relational Operators</A> | |
| 79 | <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 – Concatenation</A> | |
| 81 | <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 – Precedence</A> | |
| 83 | <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 Calls</A> | |
| 85 | <LI><A HREF="manual.html#3.4.11">3.4.11 – Function Definitions</A> | |
| 76 | <LI><A HREF="manual.html#3.4.2">3.4.2 – Coercion</A> | |
| 77 | <LI><A HREF="manual.html#3.4.3">3.4.3 – Relational Operators</A> | |
| 78 | <LI><A HREF="manual.html#3.4.4">3.4.4 – Logical Operators</A> | |
| 79 | <LI><A HREF="manual.html#3.4.5">3.4.5 – Concatenation</A> | |
| 80 | <LI><A HREF="manual.html#3.4.6">3.4.6 – The Length Operator</A> | |
| 81 | <LI><A HREF="manual.html#3.4.7">3.4.7 – Precedence</A> | |
| 82 | <LI><A HREF="manual.html#3.4.8">3.4.8 – Table Constructors</A> | |
| 83 | <LI><A HREF="manual.html#3.4.9">3.4.9 – Function Calls</A> | |
| 84 | <LI><A HREF="manual.html#3.4.10">3.4.10 – Function Definitions</A> | |
| 86 | 85 | </UL> |
| 87 | 86 | <LI><A HREF="manual.html#3.5">3.5 – Visibility Rules</A> |
| 88 | 87 | </UL> |
| r242899 | r242900 | |
| 113 | 112 | <LI><A HREF="manual.html#6.4">6.4 – String Manipulation</A> |
| 114 | 113 | <UL> |
| 115 | 114 | <LI><A HREF="manual.html#6.4.1">6.4.1 – Patterns</A> |
| 116 | <LI><A HREF="manual.html#6.4.2">6.4.2 – Format Strings for Pack and Unpack</A> | |
| 117 | 115 | </UL> |
| 118 | <LI><A HREF="manual.html#6.5">6.5 – UTF-8 Support</A> | |
| 119 | <LI><A HREF="manual.html#6.6">6.6 – Table Manipulation</A> | |
| 120 | <LI><A HREF="manual.html#6.7">6.7 – Mathematical Functions</A> | |
| 116 | <LI><A HREF="manual.html#6.5">6.5 – Table Manipulation</A> | |
| 117 | <LI><A HREF="manual.html#6.6">6.6 – Mathematical Functions</A> | |
| 118 | <LI><A HREF="manual.html#6.7">6.7 – Bitwise Operations</A> | |
| 121 | 119 | <LI><A HREF="manual.html#6.8">6.8 – Input and Output Facilities</A> |
| 122 | 120 | <LI><A HREF="manual.html#6.9">6.9 – Operating System Facilities</A> |
| 123 | 121 | <LI><A HREF="manual.html#6.10">6.10 – The Debug Library</A> |
| r242899 | r242900 | |
| 141 | 139 | <TD> |
| 142 | 140 | <H3><A NAME="functions">Lua functions</A></H3> |
| 143 | 141 | <P> |
| 144 | <A HREF="manual.html#6.1">basic</A><BR> | |
| 145 | 142 | <A HREF="manual.html#pdf-_G">_G</A><BR> |
| 146 | 143 | <A HREF="manual.html#pdf-_VERSION">_VERSION</A><BR> |
| 147 | 144 | |
| 145 | <P> | |
| 148 | 146 | <A HREF="manual.html#pdf-assert">assert</A><BR> |
| 149 | 147 | <A HREF="manual.html#pdf-collectgarbage">collectgarbage</A><BR> |
| 150 | 148 | <A HREF="manual.html#pdf-dofile">dofile</A><BR> |
| r242899 | r242900 | |
| 170 | 168 | <A HREF="manual.html#pdf-xpcall">xpcall</A><BR> |
| 171 | 169 | |
| 172 | 170 | <P> |
| 173 | <A HREF="manual.html#6.2">coroutine</A><BR> | |
| 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> | |
| 174 | 185 | <A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR> |
| 175 | <A HREF="manual.html#pdf-coroutine.isyieldable">coroutine.isyieldable</A><BR> | |
| 176 | 186 | <A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR> |
| 177 | 187 | <A HREF="manual.html#pdf-coroutine.running">coroutine.running</A><BR> |
| 178 | 188 | <A HREF="manual.html#pdf-coroutine.status">coroutine.status</A><BR> |
| r242899 | r242900 | |
| 180 | 190 | <A HREF="manual.html#pdf-coroutine.yield">coroutine.yield</A><BR> |
| 181 | 191 | |
| 182 | 192 | <P> |
| 183 | <A HREF="manual.html#6.10">debug</A><BR> | |
| 184 | 193 | <A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR> |
| 194 | <A HREF="manual.html#pdf-debug.getuservalue">debug.getuservalue</A><BR> | |
| 185 | 195 | <A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR> |
| 186 | 196 | <A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR> |
| 187 | 197 | <A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR> |
| 188 | 198 | <A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR> |
| 189 | 199 | <A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR> |
| 190 | 200 | <A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR> |
| 191 | <A HREF="manual.html#pdf-debug. | |
| 201 | <A HREF="manual.html#pdf-debug.setuservalue">debug.setuservalue</A><BR> | |
| 192 | 202 | <A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR> |
| 193 | 203 | <A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR> |
| 194 | 204 | <A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR> |
| 195 | 205 | <A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR> |
| 196 | <A HREF="manual.html#pdf-debug.setuservalue">debug.setuservalue</A><BR> | |
| 197 | 206 | <A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> |
| 198 | 207 | <A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR> |
| 199 | 208 | <A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR> |
| 200 | 209 | |
| 201 | 210 | <P> |
| 202 | <A HREF="manual.html#6.8">io</A><BR> | |
| 211 | <A HREF="manual.html#pdf-file:close">file:close</A><BR> | |
| 212 | <A HREF="manual.html#pdf-file:flush">file:flush</A><BR> | |
| 213 | <A HREF="manual.html#pdf-file:lines">file:lines</A><BR> | |
| 214 | <A HREF="manual.html#pdf-file:read">file:read</A><BR> | |
| 215 | <A HREF="manual.html#pdf-file:seek">file:seek</A><BR> | |
| 216 | <A HREF="manual.html#pdf-file:setvbuf">file:setvbuf</A><BR> | |
| 217 | <A HREF="manual.html#pdf-file:write">file:write</A><BR> | |
| 218 | ||
| 219 | <P> | |
| 203 | 220 | <A HREF="manual.html#pdf-io.close">io.close</A><BR> |
| 204 | 221 | <A HREF="manual.html#pdf-io.flush">io.flush</A><BR> |
| 205 | 222 | <A HREF="manual.html#pdf-io.input">io.input</A><BR> |
| r242899 | r242900 | |
| 215 | 232 | <A HREF="manual.html#pdf-io.type">io.type</A><BR> |
| 216 | 233 | <A HREF="manual.html#pdf-io.write">io.write</A><BR> |
| 217 | 234 | |
| 218 | <A HREF="manual.html#pdf-file:close">file:close</A><BR> | |
| 219 | <A HREF="manual.html#pdf-file:flush">file:flush</A><BR> | |
| 220 | <A HREF="manual.html#pdf-file:lines">file:lines</A><BR> | |
| 221 | <A HREF="manual.html#pdf-file:read">file:read</A><BR> | |
| 222 | <A HREF="manual.html#pdf-file:seek">file:seek</A><BR> | |
| 223 | <A HREF="manual.html#pdf-file:setvbuf">file:setvbuf</A><BR> | |
| 224 | <A HREF="manual.html#pdf-file:write">file:write</A><BR> | |
| 225 | ||
| 226 | 235 | </TD> |
| 227 | 236 | <TD> |
| 228 | 237 | <H3> </H3> |
| 229 | 238 | <P> |
| 230 | <A HREF="manual.html#6.7">math</A><BR> | |
| 231 | 239 | <A HREF="manual.html#pdf-math.abs">math.abs</A><BR> |
| 232 | 240 | <A HREF="manual.html#pdf-math.acos">math.acos</A><BR> |
| 233 | 241 | <A HREF="manual.html#pdf-math.asin">math.asin</A><BR> |
| 234 | 242 | <A HREF="manual.html#pdf-math.atan">math.atan</A><BR> |
| 243 | <A HREF="manual.html#pdf-math.atan2">math.atan2</A><BR> | |
| 235 | 244 | <A HREF="manual.html#pdf-math.ceil">math.ceil</A><BR> |
| 236 | 245 | <A HREF="manual.html#pdf-math.cos">math.cos</A><BR> |
| 246 | <A HREF="manual.html#pdf-math.cosh">math.cosh</A><BR> | |
| 237 | 247 | <A HREF="manual.html#pdf-math.deg">math.deg</A><BR> |
| 238 | 248 | <A HREF="manual.html#pdf-math.exp">math.exp</A><BR> |
| 239 | 249 | <A HREF="manual.html#pdf-math.floor">math.floor</A><BR> |
| 240 | 250 | <A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR> |
| 251 | <A HREF="manual.html#pdf-math.frexp">math.frexp</A><BR> | |
| 241 | 252 | <A HREF="manual.html#pdf-math.huge">math.huge</A><BR> |
| 253 | <A HREF="manual.html#pdf-math.ldexp">math.ldexp</A><BR> | |
| 242 | 254 | <A HREF="manual.html#pdf-math.log">math.log</A><BR> |
| 243 | 255 | <A HREF="manual.html#pdf-math.max">math.max</A><BR> |
| 244 | <A HREF="manual.html#pdf-math.maxinteger">math.maxinteger</A><BR> | |
| 245 | 256 | <A HREF="manual.html#pdf-math.min">math.min</A><BR> |
| 246 | <A HREF="manual.html#pdf-math.mininteger">math.mininteger</A><BR> | |
| 247 | 257 | <A HREF="manual.html#pdf-math.modf">math.modf</A><BR> |
| 248 | 258 | <A HREF="manual.html#pdf-math.pi">math.pi</A><BR> |
| 259 | <A HREF="manual.html#pdf-math.pow">math.pow</A><BR> | |
| 249 | 260 | <A HREF="manual.html#pdf-math.rad">math.rad</A><BR> |
| 250 | 261 | <A HREF="manual.html#pdf-math.random">math.random</A><BR> |
| 251 | 262 | <A HREF="manual.html#pdf-math.randomseed">math.randomseed</A><BR> |
| 252 | 263 | <A HREF="manual.html#pdf-math.sin">math.sin</A><BR> |
| 264 | <A HREF="manual.html#pdf-math.sinh">math.sinh</A><BR> | |
| 253 | 265 | <A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR> |
| 254 | 266 | <A HREF="manual.html#pdf-math.tan">math.tan</A><BR> |
| 255 | <A HREF="manual.html#pdf-math.tointeger">math.tointeger</A><BR> | |
| 256 | <A HREF="manual.html#pdf-math.type">math.type</A><BR> | |
| 257 | <A HREF="manual.html#pdf-math.ult">math.ult</A><BR> | |
| 267 | <A HREF="manual.html#pdf-math.tanh">math.tanh</A><BR> | |
| 258 | 268 | |
| 259 | 269 | <P> |
| 260 | <A HREF="manual.html#6.9">os</A><BR> | |
| 261 | 270 | <A HREF="manual.html#pdf-os.clock">os.clock</A><BR> |
| 262 | 271 | <A HREF="manual.html#pdf-os.date">os.date</A><BR> |
| 263 | 272 | <A HREF="manual.html#pdf-os.difftime">os.difftime</A><BR> |
| r242899 | r242900 | |
| 271 | 280 | <A HREF="manual.html#pdf-os.tmpname">os.tmpname</A><BR> |
| 272 | 281 | |
| 273 | 282 | <P> |
| 274 | <A HREF="manual.html#6.3">package</A><BR> | |
| 275 | 283 | <A HREF="manual.html#pdf-package.config">package.config</A><BR> |
| 276 | 284 | <A HREF="manual.html#pdf-package.cpath">package.cpath</A><BR> |
| 277 | 285 | <A HREF="manual.html#pdf-package.loaded">package.loaded</A><BR> |
| r242899 | r242900 | |
| 282 | 290 | <A HREF="manual.html#pdf-package.searchpath">package.searchpath</A><BR> |
| 283 | 291 | |
| 284 | 292 | <P> |
| 285 | <A HREF="manual.html#6.4">string</A><BR> | |
| 286 | 293 | <A HREF="manual.html#pdf-string.byte">string.byte</A><BR> |
| 287 | 294 | <A HREF="manual.html#pdf-string.char">string.char</A><BR> |
| 288 | 295 | <A HREF="manual.html#pdf-string.dump">string.dump</A><BR> |
| r242899 | r242900 | |
| 293 | 300 | <A HREF="manual.html#pdf-string.len">string.len</A><BR> |
| 294 | 301 | <A HREF="manual.html#pdf-string.lower">string.lower</A><BR> |
| 295 | 302 | <A HREF="manual.html#pdf-string.match">string.match</A><BR> |
| 296 | <A HREF="manual.html#pdf-string.pack">string.pack</A><BR> | |
| 297 | <A HREF="manual.html#pdf-string.packsize">string.packsize</A><BR> | |
| 298 | 303 | <A HREF="manual.html#pdf-string.rep">string.rep</A><BR> |
| 299 | 304 | <A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR> |
| 300 | 305 | <A HREF="manual.html#pdf-string.sub">string.sub</A><BR> |
| 301 | <A HREF="manual.html#pdf-string.unpack">string.unpack</A><BR> | |
| 302 | 306 | <A HREF="manual.html#pdf-string.upper">string.upper</A><BR> |
| 303 | 307 | |
| 304 | 308 | <P> |
| 305 | <A HREF="manual.html#6.6">table</A><BR> | |
| 306 | 309 | <A HREF="manual.html#pdf-table.concat">table.concat</A><BR> |
| 307 | 310 | <A HREF="manual.html#pdf-table.insert">table.insert</A><BR> |
| 308 | <A HREF="manual.html#pdf-table.move">table.move</A><BR> | |
| 309 | 311 | <A HREF="manual.html#pdf-table.pack">table.pack</A><BR> |
| 310 | 312 | <A HREF="manual.html#pdf-table.remove">table.remove</A><BR> |
| 311 | 313 | <A HREF="manual.html#pdf-table.sort">table.sort</A><BR> |
| 312 | 314 | <A HREF="manual.html#pdf-table.unpack">table.unpack</A><BR> |
| 313 | 315 | |
| 314 | <P> | |
| 315 | <A HREF="manual.html#6.5">utf8</A><BR> | |
| 316 | <A HREF="manual.html#pdf-utf8.char">utf8.char</A><BR> | |
| 317 | <A HREF="manual.html#pdf-utf8.charpattern">utf8.charpattern</A><BR> | |
| 318 | <A HREF="manual.html#pdf-utf8.codepoint">utf8.codepoint</A><BR> | |
| 319 | <A HREF="manual.html#pdf-utf8.codes">utf8.codes</A><BR> | |
| 320 | <A HREF="manual.html#pdf-utf8.len">utf8.len</A><BR> | |
| 321 | <A HREF="manual.html#pdf-utf8.offset">utf8.offset</A><BR> | |
| 322 | ||
| 323 | <H3><A NAME="env">environment<BR>variables</A></H3> | |
| 324 | <A HREF="manual.html#pdf-LUA_CPATH">LUA_CPATH</A><BR> | |
| 325 | <A HREF="manual.html#pdf-LUA_CPATH_5_3">LUA_CPATH_5_3</A><BR> | |
| 326 | <A HREF="manual.html#pdf-LUA_INIT">LUA_INIT</A><BR> | |
| 327 | <A HREF="manual.html#pdf-LUA_INIT_5_3">LUA_INIT_5_3</A><BR> | |
| 328 | <A HREF="manual.html#pdf-LUA_PATH">LUA_PATH</A><BR> | |
| 329 | <A HREF="manual.html#pdf-LUA_PATH_5_3">LUA_PATH_5_3</A><BR> | |
| 330 | ||
| 331 | 316 | </TD> |
| 332 | 317 | <TD> |
| 333 | <H3> | |
| 318 | <H3>C API</H3> | |
| 334 | 319 | <P> |
| 335 | 320 | <A HREF="manual.html#lua_Alloc">lua_Alloc</A><BR> |
| 336 | 321 | <A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR> |
| 337 | 322 | <A HREF="manual.html#lua_Debug">lua_Debug</A><BR> |
| 338 | 323 | <A HREF="manual.html#lua_Hook">lua_Hook</A><BR> |
| 339 | 324 | <A HREF="manual.html#lua_Integer">lua_Integer</A><BR> |
| 340 | <A HREF="manual.html#lua_KContext">lua_KContext</A><BR> | |
| 341 | <A HREF="manual.html#lua_KFunction">lua_KFunction</A><BR> | |
| 342 | 325 | <A HREF="manual.html#lua_Number">lua_Number</A><BR> |
| 343 | 326 | <A HREF="manual.html#lua_Reader">lua_Reader</A><BR> |
| 344 | 327 | <A HREF="manual.html#lua_State">lua_State</A><BR> |
| r242899 | r242900 | |
| 361 | 344 | <A HREF="manual.html#lua_error">lua_error</A><BR> |
| 362 | 345 | <A HREF="manual.html#lua_gc">lua_gc</A><BR> |
| 363 | 346 | <A HREF="manual.html#lua_getallocf">lua_getallocf</A><BR> |
| 364 | <A HREF="manual.html#lua_get | |
| 347 | <A HREF="manual.html#lua_getctx">lua_getctx</A><BR> | |
| 365 | 348 | <A HREF="manual.html#lua_getfield">lua_getfield</A><BR> |
| 366 | 349 | <A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR> |
| 367 | 350 | <A HREF="manual.html#lua_gethook">lua_gethook</A><BR> |
| 368 | 351 | <A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR> |
| 369 | 352 | <A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR> |
| 370 | <A HREF="manual.html#lua_geti">lua_geti</A><BR> | |
| 371 | 353 | <A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR> |
| 372 | 354 | <A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR> |
| 373 | 355 | <A HREF="manual.html#lua_getmetatable">lua_getmetatable</A><BR> |
| r242899 | r242900 | |
| 380 | 362 | <A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR> |
| 381 | 363 | <A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR> |
| 382 | 364 | <A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR> |
| 383 | <A HREF="manual.html#lua_isinteger">lua_isinteger</A><BR> | |
| 384 | 365 | <A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR> |
| 385 | 366 | <A HREF="manual.html#lua_isnil">lua_isnil</A><BR> |
| 386 | 367 | <A HREF="manual.html#lua_isnone">lua_isnone</A><BR> |
| r242899 | r242900 | |
| 390 | 371 | <A HREF="manual.html#lua_istable">lua_istable</A><BR> |
| 391 | 372 | <A HREF="manual.html#lua_isthread">lua_isthread</A><BR> |
| 392 | 373 | <A HREF="manual.html#lua_isuserdata">lua_isuserdata</A><BR> |
| 393 | <A HREF="manual.html#lua_isyieldable">lua_isyieldable</A><BR> | |
| 394 | 374 | <A HREF="manual.html#lua_len">lua_len</A><BR> |
| 395 | 375 | <A HREF="manual.html#lua_load">lua_load</A><BR> |
| 396 | 376 | <A HREF="manual.html#lua_newstate">lua_newstate</A><BR> |
| r242899 | r242900 | |
| 398 | 378 | <A HREF="manual.html#lua_newthread">lua_newthread</A><BR> |
| 399 | 379 | <A HREF="manual.html#lua_newuserdata">lua_newuserdata</A><BR> |
| 400 | 380 | <A HREF="manual.html#lua_next">lua_next</A><BR> |
| 401 | <A HREF="manual.html#lua_numbertointeger">lua_numbertointeger</A><BR> | |
| 402 | 381 | <A HREF="manual.html#lua_pcall">lua_pcall</A><BR> |
| 403 | 382 | <A HREF="manual.html#lua_pcallk">lua_pcallk</A><BR> |
| 404 | 383 | <A HREF="manual.html#lua_pop">lua_pop</A><BR> |
| r242899 | r242900 | |
| 415 | 394 | <A HREF="manual.html#lua_pushnumber">lua_pushnumber</A><BR> |
| 416 | 395 | <A HREF="manual.html#lua_pushstring">lua_pushstring</A><BR> |
| 417 | 396 | <A HREF="manual.html#lua_pushthread">lua_pushthread</A><BR> |
| 397 | <A HREF="manual.html#lua_pushunsigned">lua_pushunsigned</A><BR> | |
| 418 | 398 | <A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR> |
| 419 | 399 | <A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR> |
| 420 | 400 | <A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR> |
| r242899 | r242900 | |
| 429 | 409 | <A HREF="manual.html#lua_remove">lua_remove</A><BR> |
| 430 | 410 | <A HREF="manual.html#lua_replace">lua_replace</A><BR> |
| 431 | 411 | <A HREF="manual.html#lua_resume">lua_resume</A><BR> |
| 432 | <A HREF="manual.html#lua_rotate">lua_rotate</A><BR> | |
| 433 | 412 | <A HREF="manual.html#lua_setallocf">lua_setallocf</A><BR> |
| 434 | 413 | <A HREF="manual.html#lua_setfield">lua_setfield</A><BR> |
| 435 | 414 | <A HREF="manual.html#lua_setglobal">lua_setglobal</A><BR> |
| 436 | 415 | <A HREF="manual.html#lua_sethook">lua_sethook</A><BR> |
| 437 | <A HREF="manual.html#lua_seti">lua_seti</A><BR> | |
| 438 | 416 | <A HREF="manual.html#lua_setlocal">lua_setlocal</A><BR> |
| 439 | 417 | <A HREF="manual.html#lua_setmetatable">lua_setmetatable</A><BR> |
| 440 | 418 | <A HREF="manual.html#lua_settable">lua_settable</A><BR> |
| r242899 | r242900 | |
| 442 | 420 | <A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR> |
| 443 | 421 | <A HREF="manual.html#lua_setuservalue">lua_setuservalue</A><BR> |
| 444 | 422 | <A HREF="manual.html#lua_status">lua_status</A><BR> |
| 445 | <A HREF="manual.html#lua_stringtonumber">lua_stringtonumber</A><BR> | |
| 446 | 423 | <A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR> |
| 447 | 424 | <A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR> |
| 448 | 425 | <A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR> |
| r242899 | r242900 | |
| 453 | 430 | <A HREF="manual.html#lua_topointer">lua_topointer</A><BR> |
| 454 | 431 | <A HREF="manual.html#lua_tostring">lua_tostring</A><BR> |
| 455 | 432 | <A HREF="manual.html#lua_tothread">lua_tothread</A><BR> |
| 433 | <A HREF="manual.html#lua_tounsigned">lua_tounsigned</A><BR> | |
| 434 | <A HREF="manual.html#lua_tounsignedx">lua_tounsignedx</A><BR> | |
| 456 | 435 | <A HREF="manual.html#lua_touserdata">lua_touserdata</A><BR> |
| 457 | 436 | <A HREF="manual.html#lua_type">lua_type</A><BR> |
| 458 | 437 | <A HREF="manual.html#lua_typename">lua_typename</A><BR> |
| r242899 | r242900 | |
| 466 | 445 | |
| 467 | 446 | </TD> |
| 468 | 447 | <TD> |
| 469 | <H3> | |
| 448 | <H3>auxiliary library</H3> | |
| 470 | 449 | <P> |
| 471 | 450 | <A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR> |
| 472 | 451 | <A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR> |
| 473 | <A HREF="manual.html#luaL_Stream">luaL_Stream</A><BR> | |
| 474 | 452 | |
| 475 | 453 | <P> |
| 476 | 454 | <A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR> |
| r242899 | r242900 | |
| 484 | 462 | <A HREF="manual.html#luaL_buffinitsize">luaL_buffinitsize</A><BR> |
| 485 | 463 | <A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR> |
| 486 | 464 | <A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR> |
| 465 | <A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR> | |
| 487 | 466 | <A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR> |
| 467 | <A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR> | |
| 488 | 468 | <A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR> |
| 489 | 469 | <A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR> |
| 490 | 470 | <A HREF="manual.html#luaL_checkoption">luaL_checkoption</A><BR> |
| r242899 | r242900 | |
| 492 | 472 | <A HREF="manual.html#luaL_checkstring">luaL_checkstring</A><BR> |
| 493 | 473 | <A HREF="manual.html#luaL_checktype">luaL_checktype</A><BR> |
| 494 | 474 | <A HREF="manual.html#luaL_checkudata">luaL_checkudata</A><BR> |
| 475 | <A HREF="manual.html#luaL_checkunsigned">luaL_checkunsigned</A><BR> | |
| 495 | 476 | <A HREF="manual.html#luaL_checkversion">luaL_checkversion</A><BR> |
| 496 | 477 | <A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR> |
| 497 | 478 | <A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR> |
| r242899 | r242900 | |
| 513 | 494 | <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> |
| 514 | 495 | <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> |
| 515 | 496 | <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR> |
| 497 | <A HREF="manual.html#luaL_optint">luaL_optint</A><BR> | |
| 516 | 498 | <A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR> |
| 499 | <A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR> | |
| 517 | 500 | <A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR> |
| 518 | 501 | <A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR> |
| 519 | 502 | <A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR> |
| 503 | <A HREF="manual.html#luaL_optunsigned">luaL_optunsigned</A><BR> | |
| 520 | 504 | <A HREF="manual.html#luaL_prepbuffer">luaL_prepbuffer</A><BR> |
| 521 | 505 | <A HREF="manual.html#luaL_prepbuffsize">luaL_prepbuffsize</A><BR> |
| 522 | 506 | <A HREF="manual.html#luaL_pushresult">luaL_pushresult</A><BR> |
| r242899 | r242900 | |
| 532 | 516 | <A HREF="manual.html#luaL_unref">luaL_unref</A><BR> |
| 533 | 517 | <A HREF="manual.html#luaL_where">luaL_where</A><BR> |
| 534 | 518 | |
| 535 | <H3><A NAME="library">standard library</A></H3> | |
| 536 | <P> | |
| 537 | <A HREF="manual.html#pdf-luaopen_base">luaopen_base</A><BR> | |
| 538 | <A HREF="manual.html#pdf-luaopen_coroutine">luaopen_coroutine</A><BR> | |
| 539 | <A HREF="manual.html#pdf-luaopen_debug">luaopen_debug</A><BR> | |
| 540 | <A HREF="manual.html#pdf-luaopen_io">luaopen_io</A><BR> | |
| 541 | <A HREF="manual.html#pdf-luaopen_math">luaopen_math</A><BR> | |
| 542 | <A HREF="manual.html#pdf-luaopen_os">luaopen_os</A><BR> | |
| 543 | <A HREF="manual.html#pdf-luaopen_package">luaopen_package</A><BR> | |
| 544 | <A HREF="manual.html#pdf-luaopen_string">luaopen_string</A><BR> | |
| 545 | <A HREF="manual.html#pdf-luaopen_table">luaopen_table</A><BR> | |
| 546 | <A HREF="manual.html#pdf-luaopen_utf8">luaopen_utf8</A><BR> | |
| 547 | ||
| 548 | <H3><A NAME="constants">constants</A></H3> | |
| 549 | <A HREF="manual.html#pdf-LUA_ERRERR">LUA_ERRERR</A><BR> | |
| 550 | <A HREF="manual.html#pdf-LUA_ERRFILE">LUA_ERRFILE</A><BR> | |
| 551 | <A HREF="manual.html#pdf-LUA_ERRGCMM">LUA_ERRGCMM</A><BR> | |
| 552 | <A HREF="manual.html#pdf-LUA_ERRMEM">LUA_ERRMEM</A><BR> | |
| 553 | <A HREF="manual.html#pdf-LUA_ERRRUN">LUA_ERRRUN</A><BR> | |
| 554 | <A HREF="manual.html#pdf-LUA_ERRSYNTAX">LUA_ERRSYNTAX</A><BR> | |
| 555 | <A HREF="manual.html#pdf-LUA_HOOKCALL">LUA_HOOKCALL</A><BR> | |
| 556 | <A HREF="manual.html#pdf-LUA_HOOKCOUNT">LUA_HOOKCOUNT</A><BR> | |
| 557 | <A HREF="manual.html#pdf-LUA_HOOKLINE">LUA_HOOKLINE</A><BR> | |
| 558 | <A HREF="manual.html#pdf-LUA_HOOKRET">LUA_HOOKRET</A><BR> | |
| 559 | <A HREF="manual.html#pdf-LUA_HOOKTAILCALL">LUA_HOOKTAILCALL</A><BR> | |
| 560 | <A HREF="manual.html#pdf-LUA_MASKCALL">LUA_MASKCALL</A><BR> | |
| 561 | <A HREF="manual.html#pdf-LUA_MASKCOUNT">LUA_MASKCOUNT</A><BR> | |
| 562 | <A HREF="manual.html#pdf-LUA_MASKLINE">LUA_MASKLINE</A><BR> | |
| 563 | <A HREF="manual.html#pdf-LUA_MASKRET">LUA_MASKRET</A><BR> | |
| 564 | <A HREF="manual.html#pdf-LUA_MAXINTEGER">LUA_MAXINTEGER</A><BR> | |
| 565 | <A HREF="manual.html#pdf-LUA_MININTEGER">LUA_MININTEGER</A><BR> | |
| 566 | <A HREF="manual.html#pdf-LUA_MINSTACK">LUA_MINSTACK</A><BR> | |
| 567 | <A HREF="manual.html#pdf-LUA_MULTRET">LUA_MULTRET</A><BR> | |
| 568 | <A HREF="manual.html#pdf-LUA_NOREF">LUA_NOREF</A><BR> | |
| 569 | <A HREF="manual.html#pdf-LUA_OK">LUA_OK</A><BR> | |
| 570 | <A HREF="manual.html#pdf-LUA_OPADD">LUA_OPADD</A><BR> | |
| 571 | <A HREF="manual.html#pdf-LUA_OPBAND">LUA_OPBAND</A><BR> | |
| 572 | <A HREF="manual.html#pdf-LUA_OPBNOT">LUA_OPBNOT</A><BR> | |
| 573 | <A HREF="manual.html#pdf-LUA_OPBOR">LUA_OPBOR</A><BR> | |
| 574 | <A HREF="manual.html#pdf-LUA_OPBXOR">LUA_OPBXOR</A><BR> | |
| 575 | <A HREF="manual.html#pdf-LUA_OPDIV">LUA_OPDIV</A><BR> | |
| 576 | <A HREF="manual.html#pdf-LUA_OPEQ">LUA_OPEQ</A><BR> | |
| 577 | <A HREF="manual.html#pdf-LUA_OPIDIV">LUA_OPIDIV</A><BR> | |
| 578 | <A HREF="manual.html#pdf-LUA_OPLE">LUA_OPLE</A><BR> | |
| 579 | <A HREF="manual.html#pdf-LUA_OPLT">LUA_OPLT</A><BR> | |
| 580 | <A HREF="manual.html#pdf-LUA_OPMOD">LUA_OPMOD</A><BR> | |
| 581 | <A HREF="manual.html#pdf-LUA_OPMUL">LUA_OPMUL</A><BR> | |
| 582 | <A HREF="manual.html#pdf-LUA_OPPOW">LUA_OPPOW</A><BR> | |
| 583 | <A HREF="manual.html#pdf-LUA_OPSHL">LUA_OPSHL</A><BR> | |
| 584 | <A HREF="manual.html#pdf-LUA_OPSHR">LUA_OPSHR</A><BR> | |
| 585 | <A HREF="manual.html#pdf-LUA_OPSUB">LUA_OPSUB</A><BR> | |
| 586 | <A HREF="manual.html#pdf-LUA_OPUNM">LUA_OPUNM</A><BR> | |
| 587 | <A HREF="manual.html#pdf-LUA_REFNIL">LUA_REFNIL</A><BR> | |
| 588 | <A HREF="manual.html#pdf-LUA_REGISTRYINDEX">LUA_REGISTRYINDEX</A><BR> | |
| 589 | <A HREF="manual.html#pdf-LUA_RIDX_GLOBALS">LUA_RIDX_GLOBALS</A><BR> | |
| 590 | <A HREF="manual.html#pdf-LUA_RIDX_MAINTHREAD">LUA_RIDX_MAINTHREAD</A><BR> | |
| 591 | <A HREF="manual.html#pdf-LUA_TBOOLEAN">LUA_TBOOLEAN</A><BR> | |
| 592 | <A HREF="manual.html#pdf-LUA_TFUNCTION">LUA_TFUNCTION</A><BR> | |
| 593 | <A HREF="manual.html#pdf-LUA_TLIGHTUSERDATA">LUA_TLIGHTUSERDATA</A><BR> | |
| 594 | <A HREF="manual.html#pdf-LUA_TNIL">LUA_TNIL</A><BR> | |
| 595 | <A HREF="manual.html#pdf-LUA_TNONE">LUA_TNONE</A><BR> | |
| 596 | <A HREF="manual.html#pdf-LUA_TNUMBER">LUA_TNUMBER</A><BR> | |
| 597 | <A HREF="manual.html#pdf-LUA_TSTRING">LUA_TSTRING</A><BR> | |
| 598 | <A HREF="manual.html#pdf-LUA_TTABLE">LUA_TTABLE</A><BR> | |
| 599 | <A HREF="manual.html#pdf-LUA_TTHREAD">LUA_TTHREAD</A><BR> | |
| 600 | <A HREF="manual.html#pdf-LUA_TUSERDATA">LUA_TUSERDATA</A><BR> | |
| 601 | <A HREF="manual.html#pdf-LUA_USE_APICHECK">LUA_USE_APICHECK</A><BR> | |
| 602 | <A HREF="manual.html#pdf-LUA_YIELD">LUA_YIELD</A><BR> | |
| 603 | <A HREF="manual.html#pdf-LUAL_BUFFERSIZE">LUAL_BUFFERSIZE</A><BR> | |
| 604 | ||
| 605 | 519 | </TD> |
| 606 | 520 | </TR> |
| 607 | 521 | </TABLE> |
| r242899 | r242900 | |
| 609 | 523 | <HR> |
| 610 | 524 | <SMALL CLASS="footer"> |
| 611 | 525 | Last update: |
| 612 | Tue | |
| 526 | Tue Mar 12 11:22:18 BRT 2013 | |
| 613 | 527 | </SMALL> |
| 614 | 528 | <!-- |
| 615 | Last change: | |
| 529 | Last change: revised for Lua 5.2.2 | |
| 616 | 530 | --> |
| 617 | 531 | |
| 618 | 532 | </BODY> |
| r242899 | r242900 | |
|---|---|---|
| 1 | .TH LUA 1 "$Date: 2014/12/10 15:55:45 $" | |
| 1 | .\" $Id: lua.man,v 1.13 2011/11/16 17:16:53 lhf Exp $ | |
| 2 | .TH LUA 1 "$Date: 2011/11/16 17:16:53 $" | |
| 2 | 3 | .SH NAME |
| 3 | 4 | lua \- Lua interpreter |
| 4 | 5 | .SH SYNOPSIS |
| r242899 | r242900 | |
| 49 | 50 | prompts the user, |
| 50 | 51 | reads lines from the standard input, |
| 51 | 52 | and executes them as they are read. |
| 52 | If the line contains an expression or list of expressions, | |
| 53 | then the line is evaluated and the results are printed. | |
| 54 | 53 | If a line does not contain a complete statement, |
| 55 | 54 | then a secondary prompt is displayed and |
| 56 | 55 | lines are read until a complete statement is formed or |
| 57 | 56 | a syntax error is found. |
| 57 | If a line starts with | |
| 58 | .BR '=' , | |
| 59 | then | |
| 60 | .B lua | |
| 61 | evaluates and displays | |
| 62 | the values of the expressions in the remainder of the line. | |
| 58 | 63 | .LP |
| 59 | 64 | At the very start, |
| 60 | 65 | before even handling the command line, |
| 61 | 66 | .B lua |
| 62 | 67 | checks the contents of the environment variables |
| 63 | .B LUA_INIT_5_ | |
| 68 | .B LUA_INIT_5_2 | |
| 64 | 69 | or |
| 65 | 70 | .BR LUA_INIT , |
| 66 | 71 | in that order. |
| r242899 | r242900 | |
|---|---|---|
| 53 | 53 | a:link:hover, a:visited:hover { |
| 54 | 54 | color: #000080 ; |
| 55 | 55 | background-color: #D0D0FF ; |
| 56 | border-radius: 4px; | |
| 57 | 56 | } |
| 58 | 57 | |
| 59 | 58 | a:link:active, a:visited:active { |
| 60 | 59 | color: #FF0000 ; |
| 61 | 60 | } |
| 62 | 61 | |
| 63 | h1 a img { | |
| 64 | vertical-align: text-bottom ; | |
| 65 | } | |
| 66 | ||
| 67 | 62 | hr { |
| 68 | 63 | border: 0 ; |
| 69 | 64 | height: 1px ; |
| r242899 | r242900 | |
| 91 | 86 | input[type=text] { |
| 92 | 87 | border: solid #a0a0a0 2px ; |
| 93 | 88 | border-radius: 2em ; |
| 89 | -moz-border-radius: 2em ; | |
| 94 | 90 | background-image: url('images/search.png') ; |
| 95 | background-repeat: no-repeat | |
| 91 | background-repeat: no-repeat; | |
| 96 | 92 | background-position: 4px center ; |
| 97 | 93 | padding-left: 20px ; |
| 98 | 94 | height: 2em ; |
| 99 | 95 | } |
| 100 | 96 | |
| 101 | pre.session { | |
| 102 | background-color: #F8F8F8 ; | |
| 103 | padding: 1em ; | |
| 104 | border-radius: 8px ; | |
| 105 | } |
| r242899 | r242900 | |
|---|---|---|
| 2 | 2 | <html> |
| 3 | 3 | |
| 4 | 4 | <head> |
| 5 | <title>Lua 5. | |
| 5 | <title>Lua 5.2 Reference Manual</title> | |
| 6 | 6 | <link rel="stylesheet" type="text/css" href="lua.css"> |
| 7 | 7 | <link rel="stylesheet" type="text/css" href="manual.css"> |
| 8 | 8 | <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1"> |
| r242899 | r242900 | |
| 13 | 13 | <hr> |
| 14 | 14 | <h1> |
| 15 | 15 | <a href="http://www.lua.org/"><img src="logo.gif" alt="" border="0"></a> |
| 16 | Lua 5. | |
| 16 | Lua 5.2 Reference Manual | |
| 17 | 17 | </h1> |
| 18 | 18 | |
| 19 | 19 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes |
| 20 | 20 | <p> |
| 21 | 21 | <small> |
| 22 | Copyright © 201 | |
| 22 | Copyright © 2011–2013 Lua.org, PUC-Rio. | |
| 23 | 23 | Freely available under the terms of the |
| 24 | 24 | <a href="http://www.lua.org/license.html">Lua license</a>. |
| 25 | 25 | </small> |
| r242899 | r242900 | |
| 33 | 33 | <!-- ====================================================================== --> |
| 34 | 34 | <p> |
| 35 | 35 | |
| 36 | <!-- $Id: manual.of,v 1.1 | |
| 36 | <!-- $Id: manual.of,v 1.103 2013/03/14 18:51:56 roberto Exp $ --> | |
| 37 | 37 | |
| 38 | 38 | |
| 39 | 39 | |
| r242899 | r242900 | |
| 44 | 44 | Lua is an extension programming language designed to support |
| 45 | 45 | general procedural programming with data description |
| 46 | 46 | facilities. |
| 47 | ||
| 47 | It also offers good support for object-oriented programming, | |
| 48 | 48 | functional programming, and data-driven programming. |
| 49 | 49 | Lua is intended to be used as a powerful, lightweight, |
| 50 | 50 | embeddable scripting language for any program that needs one. |
| r242899 | r242900 | |
| 53 | 53 | |
| 54 | 54 | |
| 55 | 55 | <p> |
| 56 | ||
| 56 | Being an extension language, Lua has no notion of a "main" program: | |
| 57 | 57 | it only works <em>embedded</em> in a host client, |
| 58 | 58 | called the <em>embedding program</em> or simply the <em>host</em>. |
| 59 | 59 | The host program can invoke functions to execute a piece of Lua code, |
| r242899 | r242900 | |
| 119 | 119 | <em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>. |
| 120 | 120 | Both <b>nil</b> and <b>false</b> make a condition false; |
| 121 | 121 | any other value makes it true. |
| 122 | <em>Number</em> represents both | |
| 123 | integer numbers and real (floating-point) numbers. | |
| 122 | <em>Number</em> represents real (double-precision floating-point) numbers. | |
| 123 | Operations on numbers follow the same rules of | |
| 124 | the underlying C implementation, | |
| 125 | which, in turn, usually follows the IEEE 754 standard. | |
| 126 | (It is easy to build Lua interpreters that use other | |
| 127 | internal representations for numbers, | |
| 128 | such as single-precision floats or long integers; | |
| 129 | see file <code>luaconf.h</code>.) | |
| 124 | 130 | <em>String</em> represents immutable sequences of bytes. |
| 125 | 131 | |
| 126 | 132 | Lua is 8-bit clean: |
| 127 | 133 | strings can contain any 8-bit value, |
| 128 | 134 | including embedded zeros ('<code>\0</code>'). |
| 129 | Lua is also encoding-agnostic; | |
| 130 | it makes no assumptions about the contents of a string. | |
| 131 | 135 | |
| 132 | 136 | |
| 133 | 137 | <p> |
| 134 | The type <em>number</em> uses two internal representations, | |
| 135 | one called <em>integer</em> and the other called <em>float</em>. | |
| 136 | Lua has explicit rules about when each representation is used, | |
| 137 | but it also converts between them automatically as needed (see <a href="#3.4.3">§3.4.3</a>). | |
| 138 | Therefore, | |
| 139 | the programmer may choose to mostly ignore the difference | |
| 140 | between integers and floats | |
| 141 | or to assume complete control over the representation of each number. | |
| 142 | Standard Lua uses 64-bit integers and double-precision (64-bit) floats, | |
| 143 | but you can also compile Lua so that it | |
| 144 | uses 32-bit integers and/or single-precision (32-bit) floats. | |
| 145 | The option with 32 bits for both integers and floats | |
| 146 | is particularly attractive | |
| 147 | for small machines and embedded systems. | |
| 148 | (See macro <code>LUA_32BITS</code> in file <code>luaconf.h</code>.) | |
| 149 | ||
| 150 | ||
| 151 | <p> | |
| 152 | 138 | Lua can call (and manipulate) functions written in Lua and |
| 153 | functions written in C (see <a href="#3.4.10">§3.4.10</a>). | |
| 154 | Both are represented by the type <em>function</em>. | |
| 139 | functions written in C | |
| 140 | (see <a href="#3.4.9">§3.4.9</a>). | |
| 155 | 141 | |
| 156 | 142 | |
| 157 | 143 | <p> |
| 158 | 144 | The type <em>userdata</em> is provided to allow arbitrary C data to |
| 159 | 145 | be stored in Lua variables. |
| 160 | A userdata value | |
| 146 | A userdata value is a pointer to a block of raw memory. | |
| 161 | 147 | There are two kinds of userdata: |
| 162 | <em>full userdata</em>, | |
| 163 | which is an object with a block of memory managed by Lua, | |
| 164 | and <em>light userdata</em>, | |
| 165 | which is simply a C pointer value. | |
| 148 | full userdata, where the block of memory is managed by Lua, | |
| 149 | and light userdata, where the block of memory is managed by the host. | |
| 166 | 150 | Userdata has no predefined operations in Lua, |
| 167 | 151 | except assignment and identity test. |
| 168 | 152 | By using <em>metatables</em>, |
| r242899 | r242900 | |
| 176 | 160 | <p> |
| 177 | 161 | The type <em>thread</em> represents independent threads of execution |
| 178 | 162 | and it is used to implement coroutines (see <a href="#2.6">§2.6</a>). |
| 179 | Lua threads | |
| 163 | Do not confuse Lua threads with operating-system threads. | |
| 180 | 164 | Lua supports coroutines on all systems, |
| 181 | even those that do not support threads | |
| 165 | even those that do not support threads. | |
| 182 | 166 | |
| 183 | 167 | |
| 184 | 168 | <p> |
| 185 | 169 | The type <em>table</em> implements associative arrays, |
| 186 | 170 | that is, arrays that can be indexed not only with numbers, |
| 187 | but with any Lua value except <b>nil</b> and NaN. | |
| 188 | (<em>Not a Number</em> is a special numeric value used to represent | |
| 189 | undefined or unrepresentable results, such as <code>0/0</code>.) | |
| 171 | but with any Lua value except <b>nil</b> and NaN | |
| 172 | (<em>Not a Number</em>, a special numeric value used to represent | |
| 173 | undefined or unrepresentable results, such as <code>0/0</code>). | |
| 190 | 174 | Tables can be <em>heterogeneous</em>; |
| 191 | 175 | that is, they can contain values of all types (except <b>nil</b>). |
| 192 | 176 | Any key with value <b>nil</b> is not considered part of the table. |
| r242899 | r242900 | |
| 195 | 179 | |
| 196 | 180 | |
| 197 | 181 | <p> |
| 198 | Tables are the sole data | |
| 182 | Tables are the sole data structuring mechanism in Lua; | |
| 199 | 183 | they can be used to represent ordinary arrays, sequences, |
| 200 | 184 | symbol tables, sets, records, graphs, trees, etc. |
| 201 | 185 | To represent records, Lua uses the field name as an index. |
| 202 | 186 | The language supports this representation by |
| 203 | 187 | providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>. |
| 204 | 188 | There are several convenient ways to create tables in Lua |
| 205 | (see <a href="#3.4. | |
| 189 | (see <a href="#3.4.8">§3.4.8</a>). | |
| 206 | 190 | |
| 207 | 191 | |
| 208 | 192 | <p> |
| 209 | 193 | We use the term <em>sequence</em> to denote a table where |
| 210 | the set of all positive numeric keys is equal to {1..<em>n</em>} | |
| 211 | for some non-negative integer <em>n</em>, | |
| 212 | which is called the length of the sequence (see <a href="#3.4.7">§3.4.7</a>). | |
| 194 | the set of all positive numeric keys is equal to <em>{1..n}</em> | |
| 195 | for some integer <em>n</em>, | |
| 196 | which is called the length of the sequence (see <a href="#3.4.6">§3.4.6</a>). | |
| 213 | 197 | |
| 214 | 198 | |
| 215 | 199 | <p> |
| r242899 | r242900 | |
| 218 | 202 | In particular, |
| 219 | 203 | because functions are first-class values, |
| 220 | 204 | table fields can contain functions. |
| 221 | Thus tables can also carry <em>methods</em> (see <a href="#3.4.1 | |
| 205 | Thus tables can also carry <em>methods</em> (see <a href="#3.4.10">§3.4.10</a>). | |
| 222 | 206 | |
| 223 | 207 | |
| 224 | 208 | <p> |
| r242899 | r242900 | |
| 228 | 212 | denote the same table element |
| 229 | 213 | if and only if <code>i</code> and <code>j</code> are raw equal |
| 230 | 214 | (that is, equal without metamethods). |
| 231 | In particular, floats with integral values | |
| 232 | are equal to their respective integers | |
| 233 | (e.g., <code>1.0 == 1</code>). | |
| 234 | To avoid ambiguities, | |
| 235 | any float with integral value used as a key | |
| 236 | is converted to its respective integer. | |
| 237 | For instance, if you write <code>a[2.0] = true</code>, | |
| 238 | the actual key inserted into the table will be the | |
| 239 | integer <code>2</code>. | |
| 240 | (On the other hand, | |
| 241 | 2 and "<code>2</code>" are different Lua values and therefore | |
| 242 | denote different table entries.) | |
| 243 | 215 | |
| 244 | 216 | |
| 245 | 217 | <p> |
| r242899 | r242900 | |
| 263 | 235 | |
| 264 | 236 | <p> |
| 265 | 237 | As will be discussed in <a href="#3.2">§3.2</a> and <a href="#3.3.3">§3.3.3</a>, |
| 266 | any reference to a free name | |
| 267 | (that is, a name not bound to any declaration) <code>var</code> | |
| 268 | is syntactically translated to <code>_ENV.var</code>. | |
| 238 | any reference to a global name <code>var</code> is syntactically translated | |
| 239 | to <code>_ENV.var</code>. | |
| 269 | 240 | Moreover, every chunk is compiled in the scope of |
| 270 | an external local variable named <code>_ENV</code> (see <a href="#3.3.2">§3.3.2</a>), | |
| 271 | so <code>_ENV</code> itself is never a free name in a chunk. | |
| 241 | an external local variable called <code>_ENV</code> (see <a href="#3.3.2">§3.3.2</a>), | |
| 242 | so <code>_ENV</code> itself is never a global name in a chunk. | |
| 272 | 243 | |
| 273 | 244 | |
| 274 | 245 | <p> |
| 275 | 246 | Despite the existence of this external <code>_ENV</code> variable and |
| 276 | the translation of | |
| 247 | the translation of global names, | |
| 277 | 248 | <code>_ENV</code> is a completely regular name. |
| 278 | 249 | In particular, |
| 279 | 250 | you can define new variables and parameters with that name. |
| 280 | Each reference to a | |
| 251 | Each reference to a global name uses the <code>_ENV</code> that is | |
| 281 | 252 | visible at that point in the program, |
| 282 | 253 | following the usual visibility rules of Lua (see <a href="#3.5">§3.5</a>). |
| 283 | 254 | |
| r242899 | r242900 | |
| 289 | 260 | <p> |
| 290 | 261 | Lua keeps a distinguished environment called the <em>global environment</em>. |
| 291 | 262 | This value is kept at a special index in the C registry (see <a href="#4.5">§4.5</a>). |
| 292 | In Lua, the global variable <a href="#pdf-_G"><code>_G</code></a> is initialized with this same value. | |
| 293 | (<a href="#pdf-_G"><code>_G</code></a> is never used internally.) | |
| 263 | In Lua, the variable <a href="#pdf-_G"><code>_G</code></a> is initialized with this same value. | |
| 294 | 264 | |
| 295 | 265 | |
| 296 | 266 | <p> |
| 297 | When Lua loads a chunk, | |
| 298 | the default value for its <code>_ENV</code> upvalue | |
| 299 | is the global environment (see <a href="#pdf-load"><code>load</code></a>). | |
| 267 | When Lua compiles a chunk, | |
| 268 | it initializes the value of its <code>_ENV</code> upvalue | |
| 269 | with the global environment (see <a href="#pdf-load"><code>load</code></a>). | |
| 300 | 270 | Therefore, by default, |
| 301 | free names in Lua code refer to entries in the global environment | |
| 302 | (and, therefore, they are also called <em>global variables</em>). | |
| 271 | global variables in Lua code refer to entries in the global environment. | |
| 303 | 272 | Moreover, all standard libraries are loaded in the global environment |
| 304 | and s | |
| 273 | and several functions there operate on that environment. | |
| 305 | 274 | You can use <a href="#pdf-load"><code>load</code></a> (or <a href="#pdf-loadfile"><code>loadfile</code></a>) |
| 306 | 275 | to load a chunk with a different environment. |
| 307 | 276 | (In C, you have to load the chunk and then change the value |
| 308 | 277 | of its first upvalue.) |
| 309 | 278 | |
| 310 | 279 | |
| 280 | <p> | |
| 281 | If you change the global environment in the registry | |
| 282 | (through C code or the debug library), | |
| 283 | all chunks loaded after the change will get the new environment. | |
| 284 | Previously loaded chunks are not affected, however, | |
| 285 | as each has its own reference to the environment in its <code>_ENV</code> variable. | |
| 286 | Moreover, the variable <a href="#pdf-_G"><code>_G</code></a> | |
| 287 | (which is stored in the original global environment) | |
| 288 | is never updated by Lua. | |
| 311 | 289 | |
| 312 | 290 | |
| 313 | 291 | |
| 292 | ||
| 293 | ||
| 314 | 294 | <h2>2.3 – <a name="2.3">Error Handling</a></h2> |
| 315 | 295 | |
| 316 | 296 | <p> |
| 317 | 297 | Because Lua is an embedded extension language, |
| 318 | 298 | all Lua actions start from C code in the host program |
| 319 | calling a function from the Lua library. | |
| 320 | (When you use Lua standalone, | |
| 321 | the <code>lua</code> application is the host program.) | |
| 299 | calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>). | |
| 322 | 300 | Whenever an error occurs during |
| 323 | 301 | the compilation or execution of a Lua chunk, |
| 324 | 302 | control returns to the host, |
| r242899 | r242900 | |
| 338 | 316 | Whenever there is an error, |
| 339 | 317 | an <em>error object</em> (also called an <em>error message</em>) |
| 340 | 318 | is propagated with information about the error. |
| 341 | Lua itself only generates errors wh | |
| 319 | Lua itself only generates errors where the error object is a string, | |
| 342 | 320 | but programs may generate errors with |
| 343 | any value as the error object. | |
| 344 | It is up to the Lua program or its host to handle such error objects. | |
| 321 | any value for the error object. | |
| 345 | 322 | |
| 346 | 323 | |
| 347 | 324 | <p> |
| r242899 | r242900 | |
| 356 | 333 | This message handler is still protected by the protected call; |
| 357 | 334 | so, an error inside the message handler |
| 358 | 335 | will call the message handler again. |
| 359 | If this loop goes on for too long, | |
| 360 | Lua breaks it and returns an appropriate message. | |
| 336 | If this loop goes on, Lua breaks it and returns an appropriate message. | |
| 361 | 337 | |
| 362 | 338 | |
| 363 | 339 | |
| r242899 | r242900 | |
| 394 | 370 | You can replace the metatable of tables |
| 395 | 371 | using the <a href="#pdf-setmetatable"><code>setmetatable</code></a> function. |
| 396 | 372 | You cannot change the metatable of other types from Lua |
| 397 | (except by using the debug library | |
| 373 | (except by using the debug library); | |
| 398 | 374 | you must use the C API for that. |
| 399 | 375 | |
| 400 | 376 | |
| r242899 | r242900 | |
| 409 | 385 | |
| 410 | 386 | |
| 411 | 387 | <p> |
| 412 | A metatable controls how an object behaves in | |
| 413 | arithmetic operations, bitwise operations, | |
| 414 | order comparisons, concatenation, length operation, calls, and indexing. | |
| 388 | A metatable controls how an object behaves in arithmetic operations, | |
| 389 | order comparisons, concatenation, length operation, and indexing. | |
| 415 | 390 | A metatable also can define a function to be called |
| 416 | when a userdata or a table is garbage collected (<a href="#2.5">§2.5</a>). | |
| 391 | when a userdata or a table is garbage collected. | |
| 392 | When Lua performs one of these operations over a value, | |
| 393 | it checks whether this value has a metatable with the corresponding event. | |
| 394 | If so, the value associated with that key (the metamethod) | |
| 395 | controls how Lua will perform the operation. | |
| 417 | 396 | |
| 418 | 397 | |
| 419 | 398 | <p> |
| 420 | A detailed list of events controlled by metatables is given next. | |
| 421 | Each operation is identified by its corresponding event name. | |
| 422 | The key for each event is a string with its name prefixed by | |
| 399 | Metatables control the operations listed next. | |
| 400 | Each operation is identified by its corresponding name. | |
| 401 | The key for each operation is a string with its name prefixed by | |
| 423 | 402 | two underscores, '<code>__</code>'; |
| 424 | 403 | for instance, the key for operation "add" is the |
| 425 | 404 | string "<code>__add</code>". |
| 426 | Note that queries for metamethods are always raw; | |
| 427 | the access to a metamethod does not invoke other metamethods. | |
| 428 | You can emulate how Lua queries a metamethod for an object <code>obj</code> | |
| 429 | with the following code: | |
| 430 | 405 | |
| 406 | ||
| 407 | <p> | |
| 408 | The semantics of these operations is better explained by a Lua function | |
| 409 | describing how the interpreter executes the operation. | |
| 410 | The code shown here in Lua is only illustrative; | |
| 411 | the real behavior is hard coded in the interpreter | |
| 412 | and it is much more efficient than this simulation. | |
| 413 | All functions used in these descriptions | |
| 414 | (<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.) | |
| 415 | are described in <a href="#6.1">§6.1</a>. | |
| 416 | In particular, to retrieve the metamethod of a given object, | |
| 417 | we use the expression | |
| 418 | ||
| 431 | 419 | <pre> |
| 432 | rawget(getmetatable(obj) or {}, "__" .. event_name) | |
| 433 | </pre> | |
| 420 | metatable(obj)[event] | |
| 421 | </pre><p> | |
| 422 | This should be read as | |
| 434 | 423 | |
| 424 | <pre> | |
| 425 | rawget(getmetatable(obj) or {}, event) | |
| 426 | </pre><p> | |
| 427 | This means that the access to a metamethod does not invoke other metamethods, | |
| 428 | and access to objects with no metatables does not fail | |
| 429 | (it simply results in <b>nil</b>). | |
| 430 | ||
| 431 | ||
| 435 | 432 | <p> |
| 436 | For the unary operators (negation, length, and bitwise not), | |
| 437 | the metamethod is computed and called with a dummy second operand, | |
| 438 | equal to the first one. | |
| 439 | This extra operand is only to simplify Lua's internals | |
| 440 | (by making these operators behave like a binary operation) | |
| 441 | and may be removed in future versions. | |
| 442 | (For most uses this extra operand is irrelevant.) | |
| 433 | For the unary <code>-</code> and <code>#</code> operators, | |
| 434 | the metamethod is called with a dummy second argument. | |
| 435 | This extra argument is only to simplify Lua's internals; | |
| 436 | it may be removed in future versions and therefore it is not present | |
| 437 | in the following code. | |
| 438 | (For most uses this extra argument is irrelevant.) | |
| 443 | 439 | |
| 444 | 440 | |
| 445 | 441 | |
| r242899 | r242900 | |
| 448 | 444 | <li><b>"add": </b> |
| 449 | 445 | the <code>+</code> operation. |
| 450 | 446 | |
| 451 | If any operand for an addition is not a number | |
| 452 | (nor a string coercible to a number), | |
| 453 | Lua will try to call a metamethod. | |
| 454 | First, Lua will check the first operand (even if it is valid). | |
| 455 | If that operand does not define a metamethod for the "<code>__add</code>" event, | |
| 456 | then Lua will check the second operand. | |
| 457 | If Lua can find a metamethod, | |
| 458 | it calls the metamethod with the two operands as arguments, | |
| 459 | and the result of the call | |
| 460 | (adjusted to one value) | |
| 461 | is the result of the operation. | |
| 462 | Otherwise, | |
| 463 | it raises an error. | |
| 447 | ||
| 448 | ||
| 449 | <p> | |
| 450 | The function <code>getbinhandler</code> below defines how Lua chooses a handler | |
| 451 | for a binary operation. | |
| 452 | First, Lua tries the first operand. | |
| 453 | If its type does not define a handler for the operation, | |
| 454 | then Lua tries the second operand. | |
| 455 | ||
| 456 | <pre> | |
| 457 | function getbinhandler (op1, op2, event) | |
| 458 | return metatable(op1)[event] or metatable(op2)[event] | |
| 459 | end | |
| 460 | </pre><p> | |
| 461 | By using this function, | |
| 462 | the behavior of the <code>op1 + op2</code> is | |
| 463 | ||
| 464 | <pre> | |
| 465 | function add_event (op1, op2) | |
| 466 | local o1, o2 = tonumber(op1), tonumber(op2) | |
| 467 | if o1 and o2 then -- both operands are numeric? | |
| 468 | return o1 + o2 -- '+' here is the primitive 'add' | |
| 469 | else -- at least one of the operands is not numeric | |
| 470 | local h = getbinhandler(op1, op2, "__add") | |
| 471 | if h then | |
| 472 | -- call the handler with both operands | |
| 473 | return (h(op1, op2)) | |
| 474 | else -- no handler available: default behavior | |
| 475 | error(···) | |
| 476 | end | |
| 477 | end | |
| 478 | end | |
| 479 | </pre><p> | |
| 464 | 480 | </li> |
| 465 | 481 | |
| 466 | 482 | <li><b>"sub": </b> |
| r242899 | r242900 | |
| 484 | 500 | <li><b>"mod": </b> |
| 485 | 501 | the <code>%</code> operation. |
| 486 | 502 | |
| 487 | Behavior similar to the "add" operation. | |
| 503 | Behavior similar to the "add" operation, | |
| 504 | with the operation | |
| 505 | <code>o1 - floor(o1/o2)*o2</code> as the primitive operation. | |
| 488 | 506 | </li> |
| 489 | 507 | |
| 490 | 508 | <li><b>"pow": </b> |
| 491 | 509 | the <code>^</code> (exponentiation) operation. |
| 492 | 510 | |
| 493 | Behavior similar to the "add" operation. | |
| 511 | Behavior similar to the "add" operation, | |
| 512 | with the function <code>pow</code> (from the C math library) | |
| 513 | as the primitive operation. | |
| 494 | 514 | </li> |
| 495 | 515 | |
| 496 | 516 | <li><b>"unm": </b> |
| 497 | the <code>-</code> | |
| 517 | the unary <code>-</code> operation. | |
| 498 | 518 | |
| 499 | Behavior similar to the "add" operation. | |
| 500 | </li> | |
| 501 | 519 | |
| 502 | <li><b>"idiv": </b> | |
| 503 | the <code>//</code> (floor division) operation. | |
| 504 | ||
| 505 | Behavior similar to the "add" operation. | |
| 520 | <pre> | |
| 521 | function unm_event (op) | |
| 522 | local o = tonumber(op) | |
| 523 | if o then -- operand is numeric? | |
| 524 | return -o -- '-' here is the primitive 'unm' | |
| 525 | else -- the operand is not numeric. | |
| 526 | -- Try to get a handler from the operand | |
| 527 | local h = metatable(op).__unm | |
| 528 | if h then | |
| 529 | -- call the handler with the operand | |
| 530 | return (h(op)) | |
| 531 | else -- no handler available: default behavior | |
| 532 | error(···) | |
| 533 | end | |
| 534 | end | |
| 535 | end | |
| 536 | </pre><p> | |
| 506 | 537 | </li> |
| 507 | 538 | |
| 508 | <li><b>"band": </b> | |
| 509 | the <code>&</code> (bitwise and) operation. | |
| 539 | <li><b>"concat": </b> | |
| 540 | the <code>..</code> (concatenation) operation. | |
| 510 | 541 | |
| 511 | Behavior similar to the "add" operation, | |
| 512 | except that Lua will try a metamethod | |
| 513 | if any operator is neither an integer | |
| 514 | nor a value coercible to an integer (see <a href="#3.4.3">§3.4.3</a>). | |
| 515 | </li> | |
| 516 | 542 | |
| 517 | <li><b>"bor": </b> | |
| 518 | the <code>|</code> (bitwise or) operation. | |
| 519 | ||
| 520 | Behavior similar to the "band" operation. | |
| 543 | <pre> | |
| 544 | function concat_event (op1, op2) | |
| 545 | if (type(op1) == "string" or type(op1) == "number") and | |
| 546 | (type(op2) == "string" or type(op2) == "number") then | |
| 547 | return op1 .. op2 -- primitive string concatenation | |
| 548 | else | |
| 549 | local h = getbinhandler(op1, op2, "__concat") | |
| 550 | if h then | |
| 551 | return (h(op1, op2)) | |
| 552 | else | |
| 553 | error(···) | |
| 554 | end | |
| 555 | end | |
| 556 | end | |
| 557 | </pre><p> | |
| 521 | 558 | </li> |
| 522 | 559 | |
| 523 | <li><b>"bxor": </b> | |
| 524 | the <code>~</code> (bitwise exclusive or) operation. | |
| 560 | <li><b>"len": </b> | |
| 561 | the <code>#</code> operation. | |
| 525 | 562 | |
| 526 | Behavior similar to the "band" operation. | |
| 527 | </li> | |
| 528 | 563 | |
| 529 | <li><b>"bnot": </b> | |
| 530 | the <code>~</code> (bitwise unary not) operation. | |
| 531 | ||
| 532 | Behavior similar to the "band" operation. | |
| 564 | <pre> | |
| 565 | function len_event (op) | |
| 566 | if type(op) == "string" then | |
| 567 | return strlen(op) -- primitive string length | |
| 568 | else | |
| 569 | local h = metatable(op).__len | |
| 570 | if h then | |
| 571 | return (h(op)) -- call handler with the operand | |
| 572 | elseif type(op) == "table" then | |
| 573 | return #op -- primitive table length | |
| 574 | else -- no handler available: error | |
| 575 | error(···) | |
| 576 | end | |
| 577 | end | |
| 578 | end | |
| 579 | </pre><p> | |
| 580 | See <a href="#3.4.6">§3.4.6</a> for a description of the length of a table. | |
| 533 | 581 | </li> |
| 534 | 582 | |
| 535 | <li><b>"shl": </b> | |
| 536 | the <code><<</code> (bitwise left shift) operation. | |
| 583 | <li><b>"eq": </b> | |
| 584 | the <code>==</code> operation. | |
| 537 | 585 | |
| 538 | Behavior similar to the "band" operation. | |
| 539 | </li> | |
| 586 | The function <code>getequalhandler</code> defines how Lua chooses a metamethod | |
| 587 | for equality. | |
| 588 | A metamethod is selected only when both values | |
| 589 | being compared have the same type | |
| 590 | and the same metamethod for the selected operation, | |
| 591 | and the values are either tables or full userdata. | |
| 540 | 592 | |
| 541 | <li><b>"shr": </b> | |
| 542 | the <code>>></code> (bitwise right shift) operation. | |
| 593 | <pre> | |
| 594 | function getequalhandler (op1, op2) | |
| 595 | if type(op1) ~= type(op2) or | |
| 596 | (type(op1) ~= "table" and type(op1) ~= "userdata") then | |
| 597 | return nil -- different values | |
| 598 | end | |
| 599 | local mm1 = metatable(op1).__eq | |
| 600 | local mm2 = metatable(op2).__eq | |
| 601 | if mm1 == mm2 then return mm1 else return nil end | |
| 602 | end | |
| 603 | </pre><p> | |
| 604 | The "eq" event is defined as follows: | |
| 543 | 605 | |
| 544 | Behavior similar to the "band" operation. | |
| 606 | <pre> | |
| 607 | function eq_event (op1, op2) | |
| 608 | if op1 == op2 then -- primitive equal? | |
| 609 | return true -- values are equal | |
| 610 | end | |
| 611 | -- try metamethod | |
| 612 | local h = getequalhandler(op1, op2) | |
| 613 | if h then | |
| 614 | return not not h(op1, op2) | |
| 615 | else | |
| 616 | return false | |
| 617 | end | |
| 618 | end | |
| 619 | </pre><p> | |
| 620 | Note that the result is always a boolean. | |
| 545 | 621 | </li> |
| 546 | 622 | |
| 547 | <li><b>"concat": </b> | |
| 548 | the <code>..</code> (concatenation) operation. | |
| 623 | <li><b>"lt": </b> | |
| 624 | the <code><</code> operation. | |
| 549 | 625 | |
| 550 | Behavior similar to the "add" operation, | |
| 551 | except that Lua will try a metamethod | |
| 552 | if any operator is neither a string nor a number | |
| 553 | (which is always coercible to a string). | |
| 554 | </li> | |
| 555 | 626 | |
| 556 | <li><b>"len": </b> | |
| 557 | the <code>#</code> (length) operation. | |
| 558 | ||
| 559 | If the object is not a string, | |
| 560 | Lua will try its metamethod. | |
| 561 | If there is a metamethod, | |
| 562 | Lua calls it with the object as argument, | |
| 563 | and the result of the call | |
| 564 | (always adjusted to one value) | |
| 565 | is the result of the operation. | |
| 566 | If there is no metamethod but the object is a table, | |
| 567 | then Lua uses the table length operation (see <a href="#3.4.7">§3.4.7</a>). | |
| 568 | Otherwise, Lua raises an error. | |
| 627 | <pre> | |
| 628 | function lt_event (op1, op2) | |
| 629 | if type(op1) == "number" and type(op2) == "number" then | |
| 630 | return op1 < op2 -- numeric comparison | |
| 631 | elseif type(op1) == "string" and type(op2) == "string" then | |
| 632 | return op1 < op2 -- lexicographic comparison | |
| 633 | else | |
| 634 | local h = getbinhandler(op1, op2, "__lt") | |
| 635 | if h then | |
| 636 | return not not h(op1, op2) | |
| 637 | else | |
| 638 | error(···) | |
| 639 | end | |
| 640 | end | |
| 641 | end | |
| 642 | </pre><p> | |
| 643 | Note that the result is always a boolean. | |
| 569 | 644 | </li> |
| 570 | 645 | |
| 571 | <li><b>"eq": </b> | |
| 572 | the <code>==</code> (equal) operation. | |
| 646 | <li><b>"le": </b> | |
| 647 | the <code><=</code> operation. | |
| 573 | 648 | |
| 574 | Behavior similar to the "add" operation, | |
| 575 | except that Lua will try a metamethod only when the values | |
| 576 | being compared are either both tables or both full userdata | |
| 577 | and they are not primitively equal. | |
| 578 | The result of the call is always converted to a boolean. | |
| 579 | </li> | |
| 580 | 649 | |
| 581 | <li><b>"lt": </b> | |
| 582 | the <code><</code> (less than) operation. | |
| 650 | <pre> | |
| 651 | function le_event (op1, op2) | |
| 652 | if type(op1) == "number" and type(op2) == "number" then | |
| 653 | return op1 <= op2 -- numeric comparison | |
| 654 | elseif type(op1) == "string" and type(op2) == "string" then | |
| 655 | return op1 <= op2 -- lexicographic comparison | |
| 656 | else | |
| 657 | local h = getbinhandler(op1, op2, "__le") | |
| 658 | if h then | |
| 659 | return not not h(op1, op2) | |
| 660 | else | |
| 661 | h = getbinhandler(op1, op2, "__lt") | |
| 662 | if h then | |
| 663 | return not h(op2, op1) | |
| 664 | else | |
| 665 | error(···) | |
| 666 | end | |
| 667 | end | |
| 668 | end | |
| 669 | end | |
| 670 | </pre><p> | |
| 671 | Note that, in the absence of a "le" metamethod, | |
| 672 | Lua tries the "lt", assuming that <code>a <= b</code> is | |
| 673 | equivalent to <code>not (b < a)</code>. | |
| 583 | 674 | |
| 584 | Behavior similar to the "add" operation, | |
| 585 | except that Lua will try a metamethod only when the values | |
| 586 | being compared are neither both numbers nor both strings. | |
| 587 | The result of the call is always converted to a boolean. | |
| 588 | </li> | |
| 589 | 675 | |
| 590 | <li><b>"le": </b> | |
| 591 | the <code><=</code> (less equal) operation. | |
| 592 | ||
| 593 | Unlike other operations, | |
| 594 | The less-equal operation can use two different events. | |
| 595 | First, Lua looks for the "<code>__le</code>" metamethod in both operands, | |
| 596 | like in the "lt" operation. | |
| 597 | If it cannot find such a metamethod, | |
| 598 | then it will try the "<code>__lt</code>" event, | |
| 599 | assuming that <code>a <= b</code> is equivalent to <code>not (b < a)</code>. | |
| 676 | <p> | |
| 600 | 677 | As with the other comparison operators, |
| 601 | 678 | the result is always a boolean. |
| 602 | 679 | </li> |
| 603 | 680 | |
| 604 | 681 | <li><b>"index": </b> |
| 605 | 682 | The indexing access <code>table[key]</code>. |
| 606 | ||
| 607 | This event happens when <code>table</code> is not a table or | |
| 683 | Note that the metamethod is tried only | |
| 608 | 684 | when <code>key</code> is not present in <code>table</code>. |
| 609 | The metamethod is looked up in <code>table</code>. | |
| 685 | (When <code>table</code> is not a table, | |
| 686 | no key is ever present, | |
| 687 | so the metamethod is always tried.) | |
| 610 | 688 | |
| 611 | 689 | |
| 612 | <p> | |
| 613 | Despite the name, | |
| 614 | the metamethod for this event can be either a function or a table. | |
| 615 | If it is a function, | |
| 616 | it is called with <code>table</code> and <code>key</code> as arguments. | |
| 617 | If it is a table, | |
| 618 | the final result is the result of indexing this table with <code>key</code>. | |
| 619 | (This indexing is regular, not raw, | |
| 620 | and therefore can trigger another metamethod.) | |
| 690 | <pre> | |
| 691 | function gettable_event (table, key) | |
| 692 | local h | |
| 693 | if type(table) == "table" then | |
| 694 | local v = rawget(table, key) | |
| 695 | -- if key is present, return raw value | |
| 696 | if v ~= nil then return v end | |
| 697 | h = metatable(table).__index | |
| 698 | if h == nil then return nil end | |
| 699 | else | |
| 700 | h = metatable(table).__index | |
| 701 | if h == nil then | |
| 702 | error(···) | |
| 703 | end | |
| 704 | end | |
| 705 | if type(h) == "function" then | |
| 706 | return (h(table, key)) -- call the handler | |
| 707 | else return h[key] -- or repeat operation on it | |
| 708 | end | |
| 709 | end | |
| 710 | </pre><p> | |
| 621 | 711 | </li> |
| 622 | 712 | |
| 623 | 713 | <li><b>"newindex": </b> |
| 624 | 714 | The indexing assignment <code>table[key] = value</code>. |
| 625 | ||
| 626 | Like the index event, | |
| 627 | this event happens when <code>table</code> is not a table or | |
| 715 | Note that the metamethod is tried only | |
| 628 | 716 | when <code>key</code> is not present in <code>table</code>. |
| 629 | The metamethod is looked up in <code>table</code>. | |
| 630 | 717 | |
| 631 | 718 | |
| 632 | <p> | |
| 633 | Like with indexing, | |
| 634 | the metamethod for this event can be either a function or a table. | |
| 635 | If it is a function, | |
| 636 | it is called with <code>table</code>, <code>key</code>, and <code>value</code> as arguments. | |
| 637 | If it is a table, | |
| 638 | Lua does an indexing assignment to this table with the same key and value. | |
| 639 | (This assignment is regular, not raw, | |
| 640 | and therefore can trigger another metamethod.) | |
| 641 | ||
| 642 | ||
| 643 | <p> | |
| 644 | Whenever there is a "newindex" metamethod, | |
| 645 | Lua does not perform the primitive assignment. | |
| 646 | (If necessary, | |
| 647 | the metamethod itself can call <a href="#pdf-rawset"><code>rawset</code></a> | |
| 648 | to do the assignment.) | |
| 719 | <pre> | |
| 720 | function settable_event (table, key, value) | |
| 721 | local h | |
| 722 | if type(table) == "table" then | |
| 723 | local v = rawget(table, key) | |
| 724 | -- if key is present, do raw assignment | |
| 725 | if v ~= nil then rawset(table, key, value); return end | |
| 726 | h = metatable(table).__newindex | |
| 727 | if h == nil then rawset(table, key, value); return end | |
| 728 | else | |
| 729 | h = metatable(table).__newindex | |
| 730 | if h == nil then | |
| 731 | error(···) | |
| 732 | end | |
| 733 | end | |
| 734 | if type(h) == "function" then | |
| 735 | h(table, key,value) -- call the handler | |
| 736 | else h[key] = value -- or repeat operation on it | |
| 737 | end | |
| 738 | end | |
| 739 | </pre><p> | |
| 649 | 740 | </li> |
| 650 | 741 | |
| 651 | 742 | <li><b>"call": </b> |
| 652 | ||
| 743 | called when Lua calls a value. | |
| 653 | 744 | |
| 654 | This event happens when Lua tries to call a non-function value | |
| 655 | (that is, <code>func</code> is not a function). | |
| 656 | The metamethod is looked up in <code>func</code>. | |
| 657 | If present, | |
| 658 | the metamethod is called with <code>func</code> as its first argument, | |
| 659 | followed by the arguments of the original call (<code>args</code>). | |
| 745 | ||
| 746 | <pre> | |
| 747 | function function_event (func, ...) | |
| 748 | if type(func) == "function" then | |
| 749 | return func(...) -- primitive call | |
| 750 | else | |
| 751 | local h = metatable(func).__call | |
| 752 | if h then | |
| 753 | return h(func, ...) | |
| 754 | else | |
| 755 | error(···) | |
| 756 | end | |
| 757 | end | |
| 758 | end | |
| 759 | </pre><p> | |
| 660 | 760 | </li> |
| 661 | 761 | |
| 662 | 762 | </ul> |
| r242899 | r242900 | |
| 669 | 769 | <p> |
| 670 | 770 | Lua performs automatic memory management. |
| 671 | 771 | This means that |
| 672 | you do not have to worry about allocating memory for new objects | |
| 673 | or freeing it when the objects are no longer needed. | |
| 772 | you have to worry neither about allocating memory for new objects | |
| 773 | nor about freeing it when the objects are no longer needed. | |
| 674 | 774 | Lua manages memory automatically by running |
| 675 | 775 | a <em>garbage collector</em> to collect all <em>dead objects</em> |
| 676 | 776 | (that is, objects that are no longer accessible from Lua). |
| r242899 | r242900 | |
| 703 | 803 | memory allocation. |
| 704 | 804 | Larger values make the collector more aggressive but also increase |
| 705 | 805 | the size of each incremental step. |
| 706 | You should not use values smaller than 100, | |
| 707 | because they make the collector too slow and | |
| 806 | Values smaller than 100 make the collector too slow and | |
| 708 | 807 | can result in the collector never finishing a cycle. |
| 709 | 808 | The default is 200, |
| 710 | 809 | which means that the collector runs at "twice" |
| r242899 | r242900 | |
| 729 | 828 | the collector directly (e.g., stop and restart it). |
| 730 | 829 | |
| 731 | 830 | |
| 831 | <p> | |
| 832 | As an experimental feature in Lua 5.2, | |
| 833 | you can change the collector's operation mode | |
| 834 | from incremental to <em>generational</em>. | |
| 835 | A <em>generational collector</em> assumes that most objects die young, | |
| 836 | and therefore it traverses only young (recently created) objects. | |
| 837 | This behavior can reduce the time used by the collector, | |
| 838 | but also increases memory usage (as old dead objects may accumulate). | |
| 839 | To mitigate this second problem, | |
| 840 | from time to time the generational collector performs a full collection. | |
| 841 | Remember that this is an experimental feature; | |
| 842 | you are welcome to try it, | |
| 843 | but check your gains. | |
| 732 | 844 | |
| 845 | ||
| 846 | ||
| 733 | 847 | <h3>2.5.1 – <a name="2.5.1">Garbage-Collection Metamethods</a></h3> |
| 734 | 848 | |
| 735 | 849 | <p> |
| r242899 | r242900 | |
| 752 | 866 | Note that if you set a metatable without a <code>__gc</code> field |
| 753 | 867 | and later create that field in the metatable, |
| 754 | 868 | the object will not be marked for finalization. |
| 755 | However, after an object | |
| 869 | However, after an object is marked, | |
| 756 | 870 | you can freely change the <code>__gc</code> field of its metatable. |
| 757 | 871 | |
| 758 | 872 | |
| r242899 | r242900 | |
| 761 | 875 | it is not collected immediately by the garbage collector. |
| 762 | 876 | Instead, Lua puts it in a list. |
| 763 | 877 | After the collection, |
| 764 | Lua goes through that list. | |
| 765 | For each object in the list, | |
| 766 | it checks the object's <code>__gc</code> metamethod: | |
| 767 | If it is a function, | |
| 768 | Lua calls it with the object as its single argument; | |
| 769 | if the metamethod is not a function, | |
| 770 | Lua simply ignores it. | |
| 878 | Lua does the equivalent of the following function | |
| 879 | for each object in that list: | |
| 771 | 880 | |
| 881 | <pre> | |
| 882 | function gc_event (obj) | |
| 883 | local h = metatable(obj).__gc | |
| 884 | if type(h) == "function" then | |
| 885 | h(obj) | |
| 886 | end | |
| 887 | end | |
| 888 | </pre> | |
| 772 | 889 | |
| 773 | 890 | <p> |
| 774 | 891 | At the end of each garbage-collection cycle, |
| 775 | 892 | the finalizers for objects are called in |
| 776 | the reverse order that the | |
| 893 | the reverse order that they were marked for collection, | |
| 777 | 894 | among those collected in that cycle; |
| 778 | 895 | that is, the first finalizer to be called is the one associated |
| 779 | 896 | with the object marked last in the program. |
| r242899 | r242900 | |
| 783 | 900 | |
| 784 | 901 | <p> |
| 785 | 902 | Because the object being collected must still be used by the finalizer, |
| 786 | ||
| 903 | it (and other objects accessible only through it) | |
| 787 | 904 | must be <em>resurrected</em> by Lua. |
| 788 | 905 | Usually, this resurrection is transient, |
| 789 | 906 | and the object memory is freed in the next garbage-collection cycle. |
| 790 | 907 | However, if the finalizer stores the object in some global place |
| 791 | 908 | (e.g., a global variable), |
| 792 | then the resurrection is permanent. | |
| 793 | Moreover, if the finalizer marks a finalizing object for finalization again, | |
| 794 | its finalizer will be called again in the next cycle where the | |
| 795 | object is unreachable. | |
| 909 | then there is a permanent resurrection. | |
| 796 | 910 | In any case, |
| 797 | the object memory is freed only in the GC cycle where | |
| 798 | the object is unreachable and not marked for finalization. | |
| 911 | the object memory is freed only when it becomes completely inaccessible; | |
| 912 | its finalizer will never be called twice. | |
| 799 | 913 | |
| 800 | 914 | |
| 801 | 915 | <p> |
| 802 | 916 | When you close a state (see <a href="#lua_close"><code>lua_close</code></a>), |
| 803 | 917 | Lua calls the finalizers of all objects marked for finalization, |
| 804 | 918 | following the reverse order that they were marked. |
| 805 | If any finalizer marks objects for collection during that phase, | |
| 806 | these marks have no effect. | |
| 919 | If any finalizer marks new objects for collection during that phase, | |
| 920 | these new objects will not be finalized. | |
| 807 | 921 | |
| 808 | 922 | |
| 809 | 923 | |
| r242899 | r242900 | |
| 860 | 974 | Values, such as numbers and light C functions, |
| 861 | 975 | are not subject to garbage collection, |
| 862 | 976 | and therefore are not removed from weak tables |
| 863 | (unless | |
| 977 | (unless its associated value is collected). | |
| 864 | 978 | Although strings are subject to garbage collection, |
| 865 | 979 | they do not have an explicit construction, |
| 866 | 980 | and therefore are not removed from weak tables. |
| r242899 | r242900 | |
| 915 | 1029 | a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, |
| 916 | 1030 | the coroutine starts its execution, |
| 917 | 1031 | at the first line of its main function. |
| 918 | Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed | |
| 919 | as arguments to the coroutine's main function. | |
| 1032 | Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on | |
| 1033 | to the coroutine main function. | |
| 920 | 1034 | After the coroutine starts running, |
| 921 | 1035 | it runs until it terminates or <em>yields</em>. |
| 922 | 1036 | |
| r242899 | r242900 | |
| 926 | 1040 | normally, when its main function returns |
| 927 | 1041 | (explicitly or implicitly, after the last instruction); |
| 928 | 1042 | and abnormally, if there is an unprotected error. |
| 929 | In case of normal termination, | |
| 930 | <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>, | |
| 1043 | In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>, | |
| 931 | 1044 | plus any values returned by the coroutine main function. |
| 932 | 1045 | In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b> |
| 933 | 1046 | plus an error message. |
| r242899 | r242900 | |
| 1066 | 1179 | Lua is a case-sensitive language: |
| 1067 | 1180 | <code>and</code> is a reserved word, but <code>And</code> and <code>AND</code> |
| 1068 | 1181 | are two different, valid names. |
| 1069 | As a convention, | |
| 1070 | programs should avoid creating | |
| 1071 | names that start with an underscore followed by | |
| 1072 | one or more uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>). | |
| 1182 | As a convention, names starting with an underscore followed by | |
| 1183 | uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>) | |
| 1184 | are reserved for variables used by Lua. | |
| 1073 | 1185 | |
| 1074 | 1186 | |
| 1075 | 1187 | <p> |
| r242899 | r242900 | |
| 1077 | 1189 | |
| 1078 | 1190 | <pre> |
| 1079 | 1191 | + - * / % ^ # |
| 1080 | & ~ | << >> // | |
| 1081 | 1192 | == ~= <= >= < > = |
| 1082 | 1193 | ( ) { } [ ] :: |
| 1083 | 1194 | ; : , . .. ... |
| r242899 | r242900 | |
| 1108 | 1219 | |
| 1109 | 1220 | |
| 1110 | 1221 | <p> |
| 1111 | Strings in Lua can contain any 8-bit value, including embedded zeros, | |
| 1112 | which can be specified as '<code>\0</code>'. | |
| 1113 | More generally, | |
| 1114 | we can specify any byte in a literal string by its numerical value. | |
| 1115 | This can be done | |
| 1116 | with the escape sequence <code>\x<em>XX</em></code>, | |
| 1222 | A byte in a literal string can also be specified by its numerical value. | |
| 1223 | This can be done with the escape sequence <code>\x<em>XX</em></code>, | |
| 1117 | 1224 | where <em>XX</em> is a sequence of exactly two hexadecimal digits, |
| 1118 | 1225 | or with the escape sequence <code>\<em>ddd</em></code>, |
| 1119 | 1226 | where <em>ddd</em> is a sequence of up to three decimal digits. |
| 1120 | (Note that if a decimal escape | |
| 1227 | (Note that if a decimal escape is to be followed by a digit, | |
| 1121 | 1228 | it must be expressed using exactly three digits.) |
| 1229 | Strings in Lua can contain any 8-bit value, including embedded zeros, | |
| 1230 | which can be specified as '<code>\0</code>'. | |
| 1122 | 1231 | |
| 1123 | 1232 | |
| 1124 | 1233 | <p> |
| 1125 | The UTF-8 encoding of a Unicode character | |
| 1126 | can be inserted in a literal string with | |
| 1127 | the escape sequence <code>\u{<em>XXX</em>}</code> | |
| 1128 | (note the mandatory enclosing brackets), | |
| 1129 | where <em>XXX</em> is a sequence of one or more hexadecimal digits | |
| 1130 | representing the character code point. | |
| 1131 | ||
| 1132 | ||
| 1133 | <p> | |
| 1134 | 1234 | Literal strings can also be defined using a long format |
| 1135 | 1235 | enclosed by <em>long brackets</em>. |
| 1136 | 1236 | We define an <em>opening long bracket of level <em>n</em></em> as an opening |
| 1137 | 1237 | square bracket followed by <em>n</em> equal signs followed by another |
| 1138 | 1238 | opening square bracket. |
| 1139 | So, an opening long bracket of level 0 is written as <code>[[</code>, | |
| 1140 | an opening long bracket of level 1 is written as <code>[=[</code>, | |
| 1239 | So, an opening long bracket of level 0 is written as <code>[[</code>, | |
| 1240 | an opening long bracket of level 1 is written as <code>[=[</code>, | |
| 1141 | 1241 | and so on. |
| 1142 | 1242 | A <em>closing long bracket</em> is defined similarly; |
| 1143 | for instance, | |
| 1144 | a closing long bracket of level 4 is written as <code>]====]</code>. | |
| 1243 | for instance, a closing long bracket of level 4 is written as <code>]====]</code>. | |
| 1145 | 1244 | A <em>long literal</em> starts with an opening long bracket of any level and |
| 1146 | 1245 | ends at the first closing long bracket of the same level. |
| 1147 | It can contain any text except a closing bracket of the | |
| 1246 | It can contain any text except a closing bracket of the proper level. | |
| 1148 | 1247 | Literals in this bracketed form can run for several lines, |
| 1149 | 1248 | do not interpret any escape sequences, |
| 1150 | 1249 | and ignore long brackets of any other level. |
| r242899 | r242900 | |
| 1186 | 1285 | </pre> |
| 1187 | 1286 | |
| 1188 | 1287 | <p> |
| 1189 | A <em>numerical constant</em> (or <em>numeral</em>) | |
| 1190 | can be written with an optional fractional part | |
| 1288 | A <em>numerical constant</em> can be written with an optional fractional part | |
| 1191 | 1289 | and an optional decimal exponent, |
| 1192 | 1290 | marked by a letter '<code>e</code>' or '<code>E</code>'. |
| 1193 | 1291 | Lua also accepts hexadecimal constants, |
| r242899 | r242900 | |
| 1195 | 1293 | Hexadecimal constants also accept an optional fractional part |
| 1196 | 1294 | plus an optional binary exponent, |
| 1197 | 1295 | marked by a letter '<code>p</code>' or '<code>P</code>'. |
| 1198 | A numeric constant with a fractional dot or an exponent | |
| 1199 | denotes a float; | |
| 1200 | otherwise it denotes an integer. | |
| 1201 | Examples of valid integer constants are | |
| 1296 | Examples of valid numerical constants are | |
| 1202 | 1297 | |
| 1203 | 1298 | <pre> |
| 1204 | 3 345 0xff 0xBEBADA | |
| 1205 | </pre><p> | |
| 1206 | Examples of valid float constants are | |
| 1207 | ||
| 1208 | <pre> | |
| 1209 | 3.0 3.1416 314.16e-2 0.31416E1 34e1 | |
| 1210 | 0x0.1E 0xA23p-4 0X1.921FB54442D18P+1 | |
| 1299 | 3 3.0 3.1416 314.16e-2 0.31416E1 | |
| 1300 | 0xff 0x0.1E 0xA23p-4 0X1.921FB54442D18P+1 | |
| 1211 | 1301 | </pre> |
| 1212 | 1302 | |
| 1213 | 1303 | <p> |
| r242899 | r242900 | |
| 1376 | 1466 | <p> |
| 1377 | 1467 | Lua handles a chunk as the body of an anonymous function |
| 1378 | 1468 | with a variable number of arguments |
| 1379 | (see <a href="#3.4.1 | |
| 1469 | (see <a href="#3.4.10">§3.4.10</a>). | |
| 1380 | 1470 | As such, chunks can define local variables, |
| 1381 | 1471 | receive arguments, and return values. |
| 1382 | 1472 | Moreover, such anonymous function is compiled as in the |
| r242899 | r242900 | |
| 1388 | 1478 | <p> |
| 1389 | 1479 | A chunk can be stored in a file or in a string inside the host program. |
| 1390 | 1480 | To execute a chunk, |
| 1391 | Lua first <em>loads</em> it, | |
| 1392 | precompiling the chunk's code into instructions for a virtual machine, | |
| 1393 | and then Lua executes the compiled code | |
| 1481 | Lua first precompiles the chunk into instructions for a virtual machine, | |
| 1482 | and then it executes the compiled code | |
| 1394 | 1483 | with an interpreter for the virtual machine. |
| 1395 | 1484 | |
| 1396 | 1485 | |
| 1397 | 1486 | <p> |
| 1398 | 1487 | Chunks can also be precompiled into binary form; |
| 1399 | see program <code>luac</code> | |
| 1488 | see program <code>luac</code> for details. | |
| 1400 | 1489 | Programs in source and compiled forms are interchangeable; |
| 1401 | Lua automatically detects the file type and acts accordingly | |
| 1490 | Lua automatically detects the file type and acts accordingly. | |
| 1402 | 1491 | |
| 1403 | 1492 | |
| 1404 | 1493 | |
| 1405 | 1494 | |
| 1406 | 1495 | |
| 1496 | ||
| 1407 | 1497 | <h3>3.3.3 – <a name="3.3.3">Assignment</a></h3> |
| 1408 | 1498 | |
| 1409 | 1499 | <p> |
| r242899 | r242900 | |
| 1437 | 1527 | |
| 1438 | 1528 | <p> |
| 1439 | 1529 | The assignment statement first evaluates all its expressions |
| 1440 | and only then the assignments | |
| 1530 | and only then are the assignments performed. | |
| 1441 | 1531 | Thus the code |
| 1442 | 1532 | |
| 1443 | 1533 | <pre> |
| r242899 | r242900 | |
| 1473 | 1563 | |
| 1474 | 1564 | |
| 1475 | 1565 | <p> |
| 1476 | An assignment to a global | |
| 1566 | An assignment to a global variable <code>x = val</code> | |
| 1477 | 1567 | is equivalent to the assignment |
| 1478 | 1568 | <code>_ENV.x = val</code> (see <a href="#2.2">§2.2</a>). |
| 1479 | 1569 | |
| r242899 | r242900 | |
| 1554 | 1644 | |
| 1555 | 1645 | <p> |
| 1556 | 1646 | The <b>return</b> statement is used to return values |
| 1557 | from a function or a chunk | |
| 1558 | (which is an anonymous function). | |
| 1647 | from a function or a chunk (which is a function in disguise). | |
| 1559 | 1648 | |
| 1560 | 1649 | Functions can return more than one value, |
| 1561 | 1650 | so the syntax for the <b>return</b> statement is |
| r242899 | r242900 | |
| 1606 | 1695 | do |
| 1607 | 1696 | local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>) |
| 1608 | 1697 | if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end |
| 1609 | <em>var</em> = <em>var</em> - <em>step</em> | |
| 1610 | while true do | |
| 1611 | <em>var</em> = <em>var</em> + <em>step</em> | |
| 1612 | if (<em>step</em> >= 0 and <em>var</em> > <em>limit</em>) or (<em>step</em> < 0 and <em>var</em> < <em>limit</em>) then | |
| 1613 | break | |
| 1614 | end | |
| 1698 | 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 | |
| 1615 | 1699 | local v = <em>var</em> |
| 1616 | 1700 | <em>block</em> |
| 1701 | <em>var</em> = <em>var</em> + <em>step</em> | |
| 1617 | 1702 | end |
| 1618 | 1703 | end |
| 1619 | </pre> | |
| 1620 | ||
| 1621 | <p> | |
| 1704 | </pre><p> | |
| 1622 | 1705 | Note the following: |
| 1623 | 1706 | |
| 1624 | 1707 | <ul> |
| r242899 | r242900 | |
| 1640 | 1723 | </li> |
| 1641 | 1724 | |
| 1642 | 1725 | <li> |
| 1643 | You can use <b>break</b> | |
| 1726 | You can use <b>break</b> to exit a <b>for</b> loop. | |
| 1644 | 1727 | </li> |
| 1645 | 1728 | |
| 1646 | 1729 | <li> |
| 1647 | The loop variable <code>v</code> is local to the loop body. | |
| 1648 | If you need its value after the loop, | |
| 1649 | assign it to another variable before exiting the loop. | |
| 1730 | The loop variable <code>v</code> is local to the loop; | |
| 1731 | you cannot use its value after the <b>for</b> ends or is broken. | |
| 1732 | If you need this value, | |
| 1733 | assign it to another variable before breaking or exiting the loop. | |
| 1650 | 1734 | </li> |
| 1651 | 1735 | |
| 1652 | 1736 | </ul> |
| r242899 | r242900 | |
| 1720 | 1804 | stat ::= functioncall |
| 1721 | 1805 | </pre><p> |
| 1722 | 1806 | In this case, all returned values are thrown away. |
| 1723 | Function calls are explained in <a href="#3.4. | |
| 1807 | Function calls are explained in <a href="#3.4.9">§3.4.9</a>. | |
| 1724 | 1808 | |
| 1725 | 1809 | |
| 1726 | 1810 | |
| r242899 | r242900 | |
| 1760 | 1844 | <pre> |
| 1761 | 1845 | exp ::= prefixexp |
| 1762 | 1846 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> |
| 1763 | exp ::= Numeral | |
| 1764 | exp ::= LiteralString | |
| 1847 | exp ::= Number | |
| 1848 | exp ::= String | |
| 1765 | 1849 | exp ::= functiondef |
| 1766 | 1850 | exp ::= tableconstructor |
| 1767 | 1851 | exp ::= ‘<b>...</b>’ |
| r242899 | r242900 | |
| 1771 | 1855 | </pre> |
| 1772 | 1856 | |
| 1773 | 1857 | <p> |
| 1774 | Numer | |
| 1858 | Numbers and literal strings are explained in <a href="#3.1">§3.1</a>; | |
| 1775 | 1859 | variables are explained in <a href="#3.2">§3.2</a>; |
| 1776 | function definitions are explained in <a href="#3.4.11">§3.4.11</a>; | |
| 1777 | function calls are explained in <a href="#3.4.10">§3.4.10</a>; | |
| 1778 | table constructors are explained in <a href="#3.4.9">§3.4.9</a>. | |
| 1860 | function definitions are explained in <a href="#3.4.10">§3.4.10</a>; | |
| 1861 | function calls are explained in <a href="#3.4.9">§3.4.9</a>; | |
| 1862 | table constructors are explained in <a href="#3.4.8">§3.4.8</a>. | |
| 1779 | 1863 | Vararg expressions, |
| 1780 | 1864 | denoted by three dots ('<code>...</code>'), can only be used when |
| 1781 | 1865 | directly inside a vararg function; |
| 1782 | they are explained in <a href="#3.4.1 | |
| 1866 | they are explained in <a href="#3.4.10">§3.4.10</a>. | |
| 1783 | 1867 | |
| 1784 | 1868 | |
| 1785 | 1869 | <p> |
| 1786 | 1870 | Binary operators comprise arithmetic operators (see <a href="#3.4.1">§3.4.1</a>), |
| 1787 | bitwise operators (see <a href="#3.4.2">§3.4.2</a>), | |
| 1788 | relational operators (see <a href="#3.4.4">§3.4.4</a>), logical operators (see <a href="#3.4.5">§3.4.5</a>), | |
| 1789 | and the concatenation operator (see <a href="#3.4.6">§3.4.6</a>). | |
| 1871 | relational operators (see <a href="#3.4.3">§3.4.3</a>), logical operators (see <a href="#3.4.4">§3.4.4</a>), | |
| 1872 | and the concatenation operator (see <a href="#3.4.5">§3.4.5</a>). | |
| 1790 | 1873 | Unary operators comprise the unary minus (see <a href="#3.4.1">§3.4.1</a>), |
| 1791 | the unary bitwise not (see <a href="#3.4.2">§3.4.2</a>), | |
| 1792 | the unary logical <b>not</b> (see <a href="#3.4.5">§3.4.5</a>), | |
| 1793 | and the unary <em>length operator</em> (see <a href="#3.4.7">§3.4.7</a>). | |
| 1874 | the unary <b>not</b> (see <a href="#3.4.4">§3.4.4</a>), | |
| 1875 | and the unary <em>length operator</em> (see <a href="#3.4.6">§3.4.6</a>). | |
| 1794 | 1876 | |
| 1795 | 1877 | |
| 1796 | 1878 | <p> |
| r242899 | r242900 | |
| 1841 | 1923 | |
| 1842 | 1924 | |
| 1843 | 1925 | <h3>3.4.1 – <a name="3.4.1">Arithmetic Operators</a></h3><p> |
| 1844 | Lua supports the following arithmetic operators: | |
| 1926 | Lua supports the usual arithmetic operators: | |
| 1927 | the binary <code>+</code> (addition), | |
| 1928 | <code>-</code> (subtraction), <code>*</code> (multiplication), | |
| 1929 | <code>/</code> (division), <code>%</code> (modulo), and <code>^</code> (exponentiation); | |
| 1930 | and unary <code>-</code> (mathematical negation). | |
| 1931 | If the operands are numbers, or strings that can be converted to | |
| 1932 | numbers (see <a href="#3.4.2">§3.4.2</a>), | |
| 1933 | then all operations have the usual meaning. | |
| 1934 | Exponentiation works for any exponent. | |
| 1935 | For instance, <code>x^(-0.5)</code> computes the inverse of the square root of <code>x</code>. | |
| 1936 | Modulo is defined as | |
| 1845 | 1937 | |
| 1846 | <ul> | |
| 1847 | <li><b><code>+</code>: </b>addition</li> | |
| 1848 | <li><b><code>-</code>: </b>subtraction</li> | |
| 1849 | <li><b><code>*</code>: </b>multiplication</li> | |
| 1850 | <li><b><code>/</code>: </b>float division</li> | |
| 1851 | <li><b><code>//</code>: </b>floor division</li> | |
| 1852 | <li><b><code>%</code>: </b>modulo</li> | |
| 1853 | <li><b><code>^</code>: </b>exponentiation</li> | |
| 1854 | <li><b><code>-</code>: </b>unary minus</li> | |
| 1855 | </ul> | |
| 1938 | <pre> | |
| 1939 | a % b == a - math.floor(a/b)*b | |
| 1940 | </pre><p> | |
| 1941 | That is, it is the remainder of a division that rounds | |
| 1942 | the quotient towards minus infinity. | |
| 1856 | 1943 | |
| 1857 | <p> | |
| 1858 | With the exception of exponentiation and float division, | |
| 1859 | the arithmetic operators work as follows: | |
| 1860 | If both operands are integers, | |
| 1861 | the operation is performed over integers and the result is an integer. | |
| 1862 | Otherwise, if both operands are numbers | |
| 1863 | or strings that can be converted to | |
| 1864 | numbers (see <a href="#3.4.3">§3.4.3</a>), | |
| 1865 | then they are converted to floats, | |
| 1866 | the operation is performed following the usual rules | |
| 1867 | for floating-point arithmetic | |
| 1868 | (usually the IEEE 754 standard), | |
| 1869 | and the result is a float. | |
| 1870 | 1944 | |
| 1871 | 1945 | |
| 1872 | <p> | |
| 1873 | Exponentiation and float division (<code>/</code>) | |
| 1874 | always convert their operands to floats | |
| 1875 | and the result is always a float. | |
| 1876 | Exponentiation uses the ISO C function <code>pow</code>, | |
| 1877 | so that it works for non-integer exponents too. | |
| 1878 | 1946 | |
| 1879 | 1947 | |
| 1880 | <p> | |
| 1881 | Floor division (<code>//</code>) is a division | |
| 1882 | that rounds the quotient towards minus infinite, | |
| 1883 | that is, the floor of the division of its operands. | |
| 1948 | <h3>3.4.2 – <a name="3.4.2">Coercion</a></h3> | |
| 1884 | 1949 | |
| 1885 | ||
| 1886 | 1950 | <p> |
| 1887 | Modulo is defined as the remainder of a division | |
| 1888 | that rounds the quotient towards minus infinite (floor division). | |
| 1889 | ||
| 1890 | ||
| 1891 | <p> | |
| 1892 | In case of overflows in integer arithmetic, | |
| 1893 | all operations <em>wrap around</em>, | |
| 1894 | according to the usual rules of two-complement arithmetic. | |
| 1895 | (In other words, | |
| 1896 | they return the unique representable integer | |
| 1897 | that is equal modulo <em>2<sup>64</sup></em> to the mathematical result.) | |
| 1898 | ||
| 1899 | ||
| 1900 | ||
| 1901 | <h3>3.4.2 – <a name="3.4.2">Bitwise Operators</a></h3><p> | |
| 1902 | Lua supports the following bitwise operators: | |
| 1903 | ||
| 1904 | <ul> | |
| 1905 | <li><b><code>&</code>: </b>bitwise and</li> | |
| 1906 | <li><b><code>|</code>: </b>bitwise or</li> | |
| 1907 | <li><b><code>~</code>: </b>bitwise exclusive or</li> | |
| 1908 | <li><b><code>>></code>: </b>right shift</li> | |
| 1909 | <li><b><code><<</code>: </b>left shift</li> | |
| 1910 | <li><b><code>~</code>: </b>unary bitwise not</li> | |
| 1911 | </ul> | |
| 1912 | ||
| 1913 | <p> | |
| 1914 | All bitwise operations convert its operands to integers | |
| 1915 | (see <a href="#3.4.3">§3.4.3</a>), | |
| 1916 | operate on all bits of those integers, | |
| 1917 | and result in an integer. | |
| 1918 | ||
| 1919 | ||
| 1920 | <p> | |
| 1921 | Both right and left shifts fill the vacant bits with zeros. | |
| 1922 | Negative displacements shift to the other direction; | |
| 1923 | displacements with absolute values equal to or higher than | |
| 1924 | the number of bits in an integer | |
| 1925 | result in zero (as all bits are shifted out). | |
| 1926 | ||
| 1927 | ||
| 1928 | ||
| 1929 | ||
| 1930 | ||
| 1931 | <h3>3.4.3 – <a name="3.4.3">Coercions and Conversions</a></h3><p> | |
| 1932 | Lua provides some automatic conversions between some | |
| 1933 | types and representations at run time. | |
| 1934 | Bitwise operators always convert float operands to integers. | |
| 1935 | Exponentiation and float division | |
| 1936 | always convert integer operands to floats. | |
| 1937 | All other arithmetic operations applied to mixed numbers | |
| 1938 | (integers and floats) convert the integer operand to a float; | |
| 1939 | this is called the <em>usual rule</em>. | |
| 1940 | The C API also converts both integers to floats and | |
| 1941 | floats to integers, as needed. | |
| 1942 | Moreover, string concatenation accepts numbers as arguments, | |
| 1943 | besides strings. | |
| 1944 | ||
| 1945 | ||
| 1946 | <p> | |
| 1947 | Lua also converts strings to numbers, | |
| 1948 | whenever a number is expected. | |
| 1949 | ||
| 1950 | ||
| 1951 | <p> | |
| 1952 | In a conversion from integer to float, | |
| 1953 | if the integer value has an exact representation as a float, | |
| 1954 | that is the result. | |
| 1955 | Otherwise, | |
| 1956 | the conversion gets the nearest higher or | |
| 1957 | the nearest lower representable value. | |
| 1958 | This kind of conversion never fails. | |
| 1959 | ||
| 1960 | ||
| 1961 | <p> | |
| 1962 | The conversion from float to integer | |
| 1963 | checks whether the float has an exact representation as an integer | |
| 1964 | (that is, the float has an integral value and | |
| 1965 | it is in the range of integer representation). | |
| 1966 | If it does, that representation is the result. | |
| 1967 | Otherwise, the conversion fails. | |
| 1968 | ||
| 1969 | ||
| 1970 | <p> | |
| 1971 | The conversion from strings to numbers goes as follows: | |
| 1972 | First, the string is converted to an integer or a float, | |
| 1973 | following its syntax and the rules of the Lua lexer. | |
| 1974 | (The string may have also leading and trailing spaces and a sign.) | |
| 1975 | Then, the resulting number is converted to the required type | |
| 1976 | (float or integer) according to the previous rules. | |
| 1977 | ||
| 1978 | ||
| 1979 | <p> | |
| 1980 | The conversion from numbers to strings uses a | |
| 1981 | non-specified human-readable format. | |
| 1951 | Lua provides automatic conversion between | |
| 1952 | string and number values at run time. | |
| 1953 | Any arithmetic operation applied to a string tries to convert | |
| 1954 | this string to a number, following the rules of the Lua lexer. | |
| 1955 | (The string may have leading and trailing spaces and a sign.) | |
| 1956 | Conversely, whenever a number is used where a string is expected, | |
| 1957 | the number is converted to a string, in a reasonable format. | |
| 1982 | 1958 | For complete control over how numbers are converted to strings, |
| 1983 | 1959 | use the <code>format</code> function from the string library |
| 1984 | 1960 | (see <a href="#pdf-string.format"><code>string.format</code></a>). |
| r242899 | r242900 | |
| 1987 | 1963 | |
| 1988 | 1964 | |
| 1989 | 1965 | |
| 1990 | <h3>3.4.4 – <a name="3.4.4">Relational Operators</a></h3><p> | |
| 1991 | Lua supports the following relational operators: | |
| 1966 | <h3>3.4.3 – <a name="3.4.3">Relational Operators</a></h3><p> | |
| 1967 | The relational operators in Lua are | |
| 1992 | 1968 | |
| 1993 | <ul> | |
| 1994 | <li><b><code>==</code>: </b>equality</li> | |
| 1995 | <li><b><code>~=</code>: </b>inequality</li> | |
| 1996 | <li><b><code><</code>: </b>less than</li> | |
| 1997 | <li><b><code>></code>: </b>greater than</li> | |
| 1998 | <li><b><code><=</code>: </b>less or equal</li> | |
| 1999 | <li><b><code>>=</code>: </b>greater or equal</li> | |
| 2000 | </ul><p> | |
| 1969 | <pre> | |
| 1970 | == ~= < > <= >= | |
| 1971 | </pre><p> | |
| 2001 | 1972 | These operators always result in <b>false</b> or <b>true</b>. |
| 2002 | 1973 | |
| 2003 | 1974 | |
| r242899 | r242900 | |
| 2005 | 1976 | Equality (<code>==</code>) first compares the type of its operands. |
| 2006 | 1977 | If the types are different, then the result is <b>false</b>. |
| 2007 | 1978 | Otherwise, the values of the operands are compared. |
| 2008 | Strings are compared in the obvious way. | |
| 2009 | Numbers follow the usual rule for binary operations: | |
| 2010 | if both operands are integers, | |
| 2011 | they are compared as integers; | |
| 2012 | otherwise, they are converted to floats | |
| 2013 | and compared as such. | |
| 2014 | ||
| 2015 | ||
| 2016 | <p> | |
| 1979 | Numbers and strings are compared in the usual way. | |
| 2017 | 1980 | Tables, userdata, and threads |
| 2018 | 1981 | are compared by reference: |
| 2019 | 1982 | two objects are considered equal only if they are the same object. |
| r242899 | r242900 | |
| 2031 | 1994 | |
| 2032 | 1995 | |
| 2033 | 1996 | <p> |
| 2034 | Equality comparisons do not convert strings to numbers | |
| 2035 | or vice versa. | |
| 1997 | The conversion rules of <a href="#3.4.2">§3.4.2</a> | |
| 1998 | do not apply to equality comparisons. | |
| 2036 | 1999 | Thus, <code>"0"==0</code> evaluates to <b>false</b>, |
| 2037 | 2000 | and <code>t[0]</code> and <code>t["0"]</code> denote different |
| 2038 | 2001 | entries in a table. |
| r242899 | r242900 | |
| 2044 | 2007 | |
| 2045 | 2008 | <p> |
| 2046 | 2009 | The order operators work as follows. |
| 2047 | If both arguments are numbers, | |
| 2048 | then they are compared following | |
| 2049 | the usual rule for binary operations. | |
| 2010 | If both arguments are numbers, then they are compared as such. | |
| 2050 | 2011 | Otherwise, if both arguments are strings, |
| 2051 | 2012 | then their values are compared according to the current locale. |
| 2052 | 2013 | Otherwise, Lua tries to call the "lt" or the "le" |
| r242899 | r242900 | |
| 2058 | 2019 | |
| 2059 | 2020 | |
| 2060 | 2021 | |
| 2061 | <h3>3.4. | |
| 2022 | <h3>3.4.4 – <a name="3.4.4">Logical Operators</a></h3><p> | |
| 2062 | 2023 | The logical operators in Lua are |
| 2063 | 2024 | <b>and</b>, <b>or</b>, and <b>not</b>. |
| 2064 | 2025 | Like the control structures (see <a href="#3.3.4">§3.3.4</a>), |
| r242899 | r242900 | |
| 2074 | 2035 | The disjunction operator <b>or</b> returns its first argument |
| 2075 | 2036 | if this value is different from <b>nil</b> and <b>false</b>; |
| 2076 | 2037 | otherwise, <b>or</b> returns its second argument. |
| 2077 | Both <b>and</b> and <b>or</b> use short-c | |
| 2038 | Both <b>and</b> and <b>or</b> use short-cut evaluation; | |
| 2078 | 2039 | that is, |
| 2079 | 2040 | the second operand is evaluated only if necessary. |
| 2080 | 2041 | Here are some examples: |
| r242899 | r242900 | |
| 2096 | 2057 | |
| 2097 | 2058 | |
| 2098 | 2059 | |
| 2099 | <h3>3.4. | |
| 2060 | <h3>3.4.5 – <a name="3.4.5">Concatenation</a></h3><p> | |
| 2100 | 2061 | The string concatenation operator in Lua is |
| 2101 | 2062 | denoted by two dots ('<code>..</code>'). |
| 2102 | 2063 | If both operands are strings or numbers, then they are converted to |
| 2103 | strings according to the rules | |
| 2064 | strings according to the rules mentioned in <a href="#3.4.2">§3.4.2</a>. | |
| 2104 | 2065 | Otherwise, the <code>__concat</code> metamethod is called (see <a href="#2.4">§2.4</a>). |
| 2105 | 2066 | |
| 2106 | 2067 | |
| 2107 | 2068 | |
| 2108 | 2069 | |
| 2109 | 2070 | |
| 2110 | <h3>3.4. | |
| 2071 | <h3>3.4.6 – <a name="3.4.6">The Length Operator</a></h3> | |
| 2111 | 2072 | |
| 2112 | 2073 | <p> |
| 2113 | 2074 | The length operator is denoted by the unary prefix operator <code>#</code>. |
| r242899 | r242900 | |
| 2127 | 2088 | table is a <em>sequence</em>, |
| 2128 | 2089 | that is, |
| 2129 | 2090 | the set of its positive numeric keys is equal to <em>{1..n}</em> |
| 2130 | for some | |
| 2091 | for some integer <em>n</em>. | |
| 2131 | 2092 | In that case, <em>n</em> is its length. |
| 2132 | 2093 | Note that a table like |
| 2133 | 2094 | |
| r242899 | r242900 | |
| 2145 | 2106 | |
| 2146 | 2107 | |
| 2147 | 2108 | |
| 2148 | <h3>3.4. | |
| 2109 | <h3>3.4.7 – <a name="3.4.7">Precedence</a></h3><p> | |
| 2149 | 2110 | Operator precedence in Lua follows the table below, |
| 2150 | 2111 | from lower to higher priority: |
| 2151 | 2112 | |
| r242899 | r242900 | |
| 2153 | 2114 | or |
| 2154 | 2115 | and |
| 2155 | 2116 | < > <= >= ~= == |
| 2156 | | | |
| 2157 | ~ | |
| 2158 | & | |
| 2159 | << >> | |
| 2160 | 2117 | .. |
| 2161 | 2118 | + - |
| 2162 | * / // % | |
| 2163 | unary operators (not # - ~) | |
| 2119 | * / % | |
| 2120 | not # - (unary) | |
| 2164 | 2121 | ^ |
| 2165 | 2122 | </pre><p> |
| 2166 | 2123 | As usual, |
| r242899 | r242900 | |
| 2173 | 2130 | |
| 2174 | 2131 | |
| 2175 | 2132 | |
| 2176 | <h3>3.4. | |
| 2133 | <h3>3.4.8 – <a name="3.4.8">Table Constructors</a></h3><p> | |
| 2177 | 2134 | Table constructors are expressions that create tables. |
| 2178 | 2135 | Every time a constructor is evaluated, a new table is created. |
| 2179 | 2136 | A constructor can be used to create an empty table |
| r242899 | r242900 | |
| 2193 | 2150 | A field of the form <code>name = exp</code> is equivalent to |
| 2194 | 2151 | <code>["name"] = exp</code>. |
| 2195 | 2152 | Finally, fields of the form <code>exp</code> are equivalent to |
| 2196 | <code>[i] = exp</code>, where <code>i</code> are consecutive integers | |
| 2153 | <code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers, | |
| 2197 | 2154 | starting with 1. |
| 2198 | 2155 | Fields in the other formats do not affect this counting. |
| 2199 | 2156 | For example, |
| r242899 | r242900 | |
| 2218 | 2175 | </pre> |
| 2219 | 2176 | |
| 2220 | 2177 | <p> |
| 2221 | The order of the assignments in a constructor is undefined. | |
| 2222 | (This order would be relevant only when there are repeated keys.) | |
| 2223 | ||
| 2224 | ||
| 2225 | <p> | |
| 2226 | 2178 | If the last field in the list has the form <code>exp</code> |
| 2227 | 2179 | and the expression is a function call or a vararg expression, |
| 2228 | 2180 | then all values returned by this expression enter the list consecutively |
| 2229 | (see <a href="#3.4. | |
| 2181 | (see <a href="#3.4.9">§3.4.9</a>). | |
| 2230 | 2182 | |
| 2231 | 2183 | |
| 2232 | 2184 | <p> |
| r242899 | r242900 | |
| 2237 | 2189 | |
| 2238 | 2190 | |
| 2239 | 2191 | |
| 2240 | <h3>3.4. | |
| 2192 | <h3>3.4.9 – <a name="3.4.9">Function Calls</a></h3><p> | |
| 2241 | 2193 | A function call in Lua has the following syntax: |
| 2242 | 2194 | |
| 2243 | 2195 | <pre> |
| r242899 | r242900 | |
| 2272 | 2224 | <pre> |
| 2273 | 2225 | args ::= ‘<b>(</b>’ [explist] ‘<b>)</b>’ |
| 2274 | 2226 | args ::= tableconstructor |
| 2275 | args ::= | |
| 2227 | args ::= String | |
| 2276 | 2228 | </pre><p> |
| 2277 | 2229 | All argument expressions are evaluated before the call. |
| 2278 | 2230 | A call of the form <code>f{<em>fields</em>}</code> is |
| r242899 | r242900 | |
| 2312 | 2264 | |
| 2313 | 2265 | |
| 2314 | 2266 | |
| 2315 | <h3>3.4.1 | |
| 2267 | <h3>3.4.10 – <a name="3.4.10">Function Definitions</a></h3> | |
| 2316 | 2268 | |
| 2317 | 2269 | <p> |
| 2318 | 2270 | The syntax for function definition is |
| r242899 | r242900 | |
| 2603 | 2555 | In particular, |
| 2604 | 2556 | <em>you are responsible for controlling stack overflow</em>. |
| 2605 | 2557 | You can use the function <a href="#lua_checkstack"><code>lua_checkstack</code></a> |
| 2606 | to ensure that the stack has e | |
| 2558 | to ensure that the stack has extra slots when pushing new elements. | |
| 2607 | 2559 | |
| 2608 | 2560 | |
| 2609 | 2561 | <p> |
| 2610 | 2562 | Whenever Lua calls C, |
| 2611 | it ensures that the stack has space for | |
| 2612 | at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots. | |
| 2563 | it ensures that the stack has at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots. | |
| 2613 | 2564 | <code>LUA_MINSTACK</code> is defined as 20, |
| 2614 | 2565 | so that usually you do not have to worry about stack space |
| 2615 | 2566 | unless your code has loops pushing elements onto the stack. |
| r242899 | r242900 | |
| 2618 | 2569 | <p> |
| 2619 | 2570 | When you call a Lua function |
| 2620 | 2571 | without a fixed number of results (see <a href="#lua_call"><code>lua_call</code></a>), |
| 2621 | Lua ensures that the stack has enough s | |
| 2572 | Lua ensures that the stack has enough size for all results, | |
| 2622 | 2573 | but it does not ensure any extra space. |
| 2623 | 2574 | So, before pushing anything in the stack after such a call |
| 2624 | 2575 | you should use <a href="#lua_checkstack"><code>lua_checkstack</code></a>. |
| r242899 | r242900 | |
| 2722 | 2673 | <a name="pdf-LUA_REGISTRYINDEX"><code>LUA_REGISTRYINDEX</code></a>, |
| 2723 | 2674 | which is a valid index. |
| 2724 | 2675 | Any C library can store data into this table, |
| 2725 | but it | |
| 2676 | but it should take care to choose keys | |
| 2726 | 2677 | that are different from those used |
| 2727 | 2678 | by other libraries, to avoid collisions. |
| 2728 | 2679 | Typically, you should use as key a string containing your library name, |
| 2729 | 2680 | or a light userdata with the address of a C object in your code, |
| 2730 | 2681 | or any Lua object created by your code. |
| 2731 | As with | |
| 2682 | As with global names, | |
| 2732 | 2683 | string keys starting with an underscore followed by |
| 2733 | 2684 | uppercase letters are reserved for Lua. |
| 2734 | 2685 | |
| 2735 | 2686 | |
| 2736 | 2687 | <p> |
| 2737 | The integer keys in the registry are used | |
| 2738 | by the reference mechanism (see <a href="#luaL_ref"><code>luaL_ref</code></a>) | |
| 2688 | The integer keys in the registry are used by the reference mechanism, | |
| 2689 | implemented by the auxiliary library, | |
| 2739 | 2690 | and by some predefined values. |
| 2740 | Therefore, integer keys | |
| 2691 | Therefore, integer keys should not be used for other purposes. | |
| 2741 | 2692 | |
| 2742 | 2693 | |
| 2743 | 2694 | <p> |
| r242899 | r242900 | |
| 2765 | 2716 | |
| 2766 | 2717 | <p> |
| 2767 | 2718 | Internally, Lua uses the C <code>longjmp</code> facility to handle errors. |
| 2768 | (Lua will use exceptions if you compile it as C++; | |
| 2769 | search for <code>LUAI_THROW</code> in the source code for details.) | |
| 2719 | (You can also choose to use exceptions if you compile Lua as C++; | |
| 2720 | search for <code>LUAI_THROW</code> in the source code.) | |
| 2770 | 2721 | When Lua faces any error |
| 2771 | 2722 | (such as a memory allocation error, type errors, syntax errors, |
| 2772 | 2723 | and runtime errors) |
| r242899 | r242900 | |
| 2790 | 2741 | <p> |
| 2791 | 2742 | The panic function runs as if it were a message handler (see <a href="#2.3">§2.3</a>); |
| 2792 | 2743 | in particular, the error message is at the top of the stack. |
| 2793 | However, there is no guarantee about stack space. | |
| 2744 | However, there is no guarantees about stack space. | |
| 2794 | 2745 | To push anything on the stack, |
| 2795 | the panic function | |
| 2746 | the panic function should first check the available space (see <a href="#4.2">§4.2</a>). | |
| 2796 | 2747 | |
| 2797 | 2748 | |
| 2798 | 2749 | <p> |
| 2799 | Most functions in the API can r | |
| 2750 | Most functions in the API can throw an error, | |
| 2800 | 2751 | for instance due to a memory allocation error. |
| 2801 | 2752 | The documentation for each function indicates whether |
| 2802 | it can r | |
| 2753 | it can throw errors. | |
| 2803 | 2754 | |
| 2804 | 2755 | |
| 2805 | 2756 | <p> |
| 2806 | Inside a C function you can r | |
| 2757 | Inside a C function you can throw an error by calling <a href="#lua_error"><code>lua_error</code></a>. | |
| 2807 | 2758 | |
| 2808 | 2759 | |
| 2809 | 2760 | |
| r242899 | r242900 | |
| 2813 | 2764 | |
| 2814 | 2765 | <p> |
| 2815 | 2766 | Internally, Lua uses the C <code>longjmp</code> facility to yield a coroutine. |
| 2816 | Therefore, if a | |
| 2767 | Therefore, if a function <code>foo</code> calls an API function | |
| 2817 | 2768 | and this API function yields |
| 2818 | 2769 | (directly or indirectly by calling another function that yields), |
| 2819 | 2770 | Lua cannot return to <code>foo</code> any more, |
| r242899 | r242900 | |
| 2826 | 2777 | except for three functions: |
| 2827 | 2778 | <a href="#lua_yieldk"><code>lua_yieldk</code></a>, <a href="#lua_callk"><code>lua_callk</code></a>, and <a href="#lua_pcallk"><code>lua_pcallk</code></a>. |
| 2828 | 2779 | All those functions receive a <em>continuation function</em> |
| 2829 | (as a parameter | |
| 2780 | (as a parameter called <code>k</code>) to continue execution after a yield. | |
| 2830 | 2781 | |
| 2831 | 2782 | |
| 2832 | 2783 | <p> |
| r242899 | r242900 | |
| 2856 | 2807 | |
| 2857 | 2808 | |
| 2858 | 2809 | <p> |
| 2859 | As an illustration, consider the following function: | |
| 2860 | ||
| 2861 | <pre> | |
| 2862 | int original_function (lua_State *L) { | |
| 2863 | ... /* code 1 */ | |
| 2864 | status = lua_pcall(L, n, m, h); /* calls Lua */ | |
| 2865 | ... /* code 2 */ | |
| 2866 | } | |
| 2867 | </pre><p> | |
| 2868 | Now we want to allow | |
| 2869 | the Lua code being run by <a href="#lua_pcall"><code>lua_pcall</code></a> to yield. | |
| 2870 | First, we can rewrite our function like here: | |
| 2871 | ||
| 2872 | <pre> | |
| 2873 | int k (lua_State *L, int status, lua_KContext ctx) { | |
| 2874 | ... /* code 2 */ | |
| 2875 | } | |
| 2876 | ||
| 2877 | int original_function (lua_State *L) { | |
| 2878 | ... /* code 1 */ | |
| 2879 | return k(L, lua_pcall(L, n, m, h), ctx); | |
| 2880 | } | |
| 2881 | </pre><p> | |
| 2882 | In the above code, | |
| 2883 | the new function <code>k</code> is a | |
| 2884 | <em>continuation function</em> (with type <a href="#lua_KFunction"><code>lua_KFunction</code></a>), | |
| 2885 | which should do all the work that the original function | |
| 2886 | was doing after calling <a href="#lua_pcall"><code>lua_pcall</code></a>. | |
| 2887 | Now, we must inform Lua that it must call <code>k</code> if the Lua code | |
| 2888 | being executed by <a href="#lua_pcall"><code>lua_pcall</code></a> gets interrupted in some way | |
| 2889 | (errors or yielding), | |
| 2890 | so we rewrite the code as here, | |
| 2891 | replacing <a href="#lua_pcall"><code>lua_pcall</code></a> by <a href="#lua_pcallk"><code>lua_pcallk</code></a>: | |
| 2892 | ||
| 2893 | <pre> | |
| 2894 | int original_function (lua_State *L) { | |
| 2895 | ... /* code 1 */ | |
| 2896 | return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1); | |
| 2897 | } | |
| 2898 | </pre><p> | |
| 2899 | Note the external, explicit call to the continuation: | |
| 2900 | Lua will call the continuation only if needed, that is, | |
| 2901 | in case of errors or resuming after a yield. | |
| 2902 | If the called function returns normally without ever yielding, | |
| 2903 | <a href="#lua_pcallk"><code>lua_pcallk</code></a> (and <a href="#lua_callk"><code>lua_callk</code></a>) will also return normally. | |
| 2904 | (Of course, instead of calling the continuation in that case, | |
| 2905 | you can do the equivalent work directly inside the original function.) | |
| 2906 | ||
| 2907 | ||
| 2908 | <p> | |
| 2909 | Besides the Lua state, | |
| 2910 | the continuation function has two other parameters: | |
| 2911 | the final status of the call plus the context value (<code>ctx</code>) that | |
| 2912 | was passed originally to <a href="#lua_pcallk"><code>lua_pcallk</code></a>. | |
| 2913 | (Lua does not use this context value; | |
| 2914 | it only passes this value from the original function to the | |
| 2915 | continuation function.) | |
| 2916 | For <a href="#lua_pcallk"><code>lua_pcallk</code></a>, | |
| 2917 | the status is the same value that would be returned by <a href="#lua_pcallk"><code>lua_pcallk</code></a>, | |
| 2918 | except that it is <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> when being executed after a yield | |
| 2919 | (instead of <a href="#pdf-LUA_OK"><code>LUA_OK</code></a>). | |
| 2920 | For <a href="#lua_yieldk"><code>lua_yieldk</code></a> and <a href="#lua_callk"><code>lua_callk</code></a>, | |
| 2921 | the status is always <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> when Lua calls the continuation. | |
| 2922 | (For these two functions, | |
| 2923 | Lua will not call the continuation in case of errors, | |
| 2924 | because they do not handle errors.) | |
| 2925 | Similarly, when using <a href="#lua_callk"><code>lua_callk</code></a>, | |
| 2926 | you should call the continuation function | |
| 2927 | with <a href="#pdf-LUA_OK"><code>LUA_OK</code></a> as the status. | |
| 2928 | (For <a href="#lua_yieldk"><code>lua_yieldk</code></a>, there is not much point in calling | |
| 2929 | directly the continuation function, | |
| 2930 | because <a href="#lua_yieldk"><code>lua_yieldk</code></a> usually does not return.) | |
| 2931 | ||
| 2932 | ||
| 2933 | <p> | |
| 2934 | 2810 | Lua treats the continuation function as if it were the original function. |
| 2935 | 2811 | The continuation function receives the same Lua stack |
| 2936 | 2812 | from the original function, |
| r242899 | r242900 | |
| 2943 | 2819 | of the original function. |
| 2944 | 2820 | |
| 2945 | 2821 | |
| 2822 | <p> | |
| 2823 | The only difference in the Lua state between the original function | |
| 2824 | and its continuation is the result of a call to <a href="#lua_getctx"><code>lua_getctx</code></a>. | |
| 2946 | 2825 | |
| 2947 | 2826 | |
| 2948 | 2827 | |
| 2828 | ||
| 2829 | ||
| 2949 | 2830 | <h2>4.8 – <a name="4.8">Functions and Types</a></h2> |
| 2950 | 2831 | |
| 2951 | 2832 | <p> |
| r242899 | r242900 | |
| 2969 | 2850 | by looking only at its arguments |
| 2970 | 2851 | (e.g., they may depend on what is on the stack). |
| 2971 | 2852 | The third field, <code>x</code>, |
| 2972 | tells whether the function may raise errors: | |
| 2973 | '<code>-</code>' means the function never raises any error; | |
| 2974 | '<code>e</code>' means the function may raise errors; | |
| 2975 | '<code>v</code>' means the function may raise an error on purpose. | |
| 2853 | tells whether the function may throw errors: | |
| 2854 | '<code>-</code>' means the function never throws any error; | |
| 2855 | '<code>e</code>' means the function may throw errors; | |
| 2856 | '<code>v</code>' means the function may throw an error on purpose. | |
| 2976 | 2857 | |
| 2977 | 2858 | |
| 2978 | 2859 | |
| r242899 | r242900 | |
| 3004 | 2885 | <code>ptr</code>, a pointer to the block being allocated/reallocated/freed; |
| 3005 | 2886 | <code>osize</code>, the original size of the block or some code about what |
| 3006 | 2887 | is being allocated; |
| 3007 | ||
| 2888 | <code>nsize</code>, the new size of the block. | |
| 3008 | 2889 | |
| 3009 | 2890 | |
| 3010 | 2891 | <p> |
| r242899 | r242900 | |
| 3030 | 2911 | |
| 3031 | 2912 | <p> |
| 3032 | 2913 | When <code>nsize</code> is zero, |
| 3033 | the allocator | |
| 2914 | the allocator should behave like <code>free</code> | |
| 3034 | 2915 | and return <code>NULL</code>. |
| 3035 | 2916 | |
| 3036 | 2917 | |
| 3037 | 2918 | <p> |
| 3038 | 2919 | When <code>nsize</code> is not zero, |
| 3039 | the allocator | |
| 2920 | the allocator should behave like <code>realloc</code>. | |
| 3040 | 2921 | The allocator returns <code>NULL</code> |
| 3041 | 2922 | if and only if it cannot fulfill the request. |
| 3042 | 2923 | Lua assumes that the allocator never fails when |
| r242899 | r242900 | |
| 3061 | 2942 | </pre><p> |
| 3062 | 2943 | Note that Standard C ensures |
| 3063 | 2944 | that <code>free(NULL)</code> has no effect and that |
| 3064 | <code>realloc(NULL,size)</code> is equivalent to <code>malloc(size)</code>. | |
| 2945 | <code>realloc(NULL, size)</code> is equivalent to <code>malloc(size)</code>. | |
| 3065 | 2946 | This code assumes that <code>realloc</code> does not fail when shrinking a block. |
| 3066 | 2947 | (Although Standard C does not ensure this behavior, |
| 3067 | 2948 | it seems to be a safe assumption.) |
| r242899 | r242900 | |
| 3075 | 2956 | <pre>void lua_arith (lua_State *L, int op);</pre> |
| 3076 | 2957 | |
| 3077 | 2958 | <p> |
| 3078 | Performs an arithmetic or bitwise operation over the two values | |
| 3079 | (or one, in the case of negations) | |
| 2959 | Performs an arithmetic operation over the two values | |
| 2960 | (or one, in the case of negation) | |
| 3080 | 2961 | at the top of the stack, |
| 3081 | 2962 | with the value at the top being the second operand, |
| 3082 | 2963 | pops these values, and pushes the result of the operation. |
| r242899 | r242900 | |
| 3092 | 2973 | <li><b><a name="pdf-LUA_OPADD"><code>LUA_OPADD</code></a>: </b> performs addition (<code>+</code>)</li> |
| 3093 | 2974 | <li><b><a name="pdf-LUA_OPSUB"><code>LUA_OPSUB</code></a>: </b> performs subtraction (<code>-</code>)</li> |
| 3094 | 2975 | <li><b><a name="pdf-LUA_OPMUL"><code>LUA_OPMUL</code></a>: </b> performs multiplication (<code>*</code>)</li> |
| 3095 | <li><b><a name="pdf-LUA_OPDIV"><code>LUA_OPDIV</code></a>: </b> performs float division (<code>/</code>)</li> | |
| 3096 | <li><b><a name="pdf-LUA_OPIDIV"><code>LUA_OPIDIV</code></a>: </b> performs floor division (<code>//</code>)</li> | |
| 2976 | <li><b><a name="pdf-LUA_OPDIV"><code>LUA_OPDIV</code></a>: </b> performs division (<code>/</code>)</li> | |
| 3097 | 2977 | <li><b><a name="pdf-LUA_OPMOD"><code>LUA_OPMOD</code></a>: </b> performs modulo (<code>%</code>)</li> |
| 3098 | 2978 | <li><b><a name="pdf-LUA_OPPOW"><code>LUA_OPPOW</code></a>: </b> performs exponentiation (<code>^</code>)</li> |
| 3099 | 2979 | <li><b><a name="pdf-LUA_OPUNM"><code>LUA_OPUNM</code></a>: </b> performs mathematical negation (unary <code>-</code>)</li> |
| 3100 | <li><b><a name="pdf-LUA_OPBNOT"><code>LUA_OPBNOT</code></a>: </b> performs bitwise negation (<code>~</code>)</li> | |
| 3101 | <li><b><a name="pdf-LUA_OPBAND"><code>LUA_OPBAND</code></a>: </b> performs bitwise and (<code>&</code>)</li> | |
| 3102 | <li><b><a name="pdf-LUA_OPBOR"><code>LUA_OPBOR</code></a>: </b> performs bitwise or (<code>|</code>)</li> | |
| 3103 | <li><b><a name="pdf-LUA_OPBXOR"><code>LUA_OPBXOR</code></a>: </b> performs bitwise exclusive or (<code>~</code>)</li> | |
| 3104 | <li><b><a name="pdf-LUA_OPSHL"><code>LUA_OPSHL</code></a>: </b> performs left shift (<code><<</code>)</li> | |
| 3105 | <li><b><a name="pdf-LUA_OPSHR"><code>LUA_OPSHR</code></a>: </b> performs right shift (<code>>></code>)</li> | |
| 3106 | 2980 | |
| 3107 | 2981 | </ul> |
| 3108 | 2982 | |
| r242899 | r242900 | |
| 3164 | 3038 | |
| 3165 | 3039 | <pre> |
| 3166 | 3040 | lua_getglobal(L, "f"); /* function to be called */ |
| 3167 | lua_push | |
| 3041 | lua_pushstring(L, "how"); /* 1st argument */ | |
| 3168 | 3042 | lua_getglobal(L, "t"); /* table to be indexed */ |
| 3169 | 3043 | lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ |
| 3170 | 3044 | lua_remove(L, -2); /* remove 't' from the stack */ |
| r242899 | r242900 | |
| 3172 | 3046 | lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */ |
| 3173 | 3047 | lua_setglobal(L, "a"); /* set global 'a' */ |
| 3174 | 3048 | </pre><p> |
| 3175 | Note that the code above is | |
| 3049 | Note that the code above is "balanced": | |
| 3176 | 3050 | at its end, the stack is back to its original configuration. |
| 3177 | 3051 | This is considered good programming practice. |
| 3178 | 3052 | |
| r242899 | r242900 | |
| 3182 | 3056 | |
| 3183 | 3057 | <hr><h3><a name="lua_callk"><code>lua_callk</code></a></h3><p> |
| 3184 | 3058 | <span class="apii">[-(nargs + 1), +nresults, <em>e</em>]</span> |
| 3185 | <pre>void lua_callk (lua_State *L, | |
| 3186 | int nargs, | |
| 3187 | int nresults, | |
| 3188 | lua_KContext ctx, | |
| 3189 | lua_KFunction k);</pre> | |
| 3059 | <pre>void lua_callk (lua_State *L, int nargs, int nresults, int ctx, | |
| 3060 | lua_CFunction k);</pre> | |
| 3190 | 3061 | |
| 3191 | 3062 | <p> |
| 3192 | 3063 | This function behaves exactly like <a href="#lua_call"><code>lua_call</code></a>, |
| r242899 | r242900 | |
| 3224 | 3095 | |
| 3225 | 3096 | <p> |
| 3226 | 3097 | As an example, the following function receives a variable number |
| 3227 | of numerical arguments and returns their average and | |
| 3098 | of numerical arguments and returns their average and sum: | |
| 3228 | 3099 | |
| 3229 | 3100 | <pre> |
| 3230 | 3101 | static int foo (lua_State *L) { |
| 3231 | 3102 | int n = lua_gettop(L); /* number of arguments */ |
| 3232 | lua_Number sum = 0 | |
| 3103 | lua_Number sum = 0; | |
| 3233 | 3104 | int i; |
| 3234 | 3105 | for (i = 1; i <= n; i++) { |
| 3235 | 3106 | if (!lua_isnumber(L, i)) { |
| 3236 | lua_push | |
| 3107 | lua_pushstring(L, "incorrect argument"); | |
| 3237 | 3108 | lua_error(L); |
| 3238 | 3109 | } |
| 3239 | 3110 | sum += lua_tonumber(L, i); |
| r242899 | r242900 | |
| 3249 | 3120 | |
| 3250 | 3121 | <hr><h3><a name="lua_checkstack"><code>lua_checkstack</code></a></h3><p> |
| 3251 | 3122 | <span class="apii">[-0, +0, –]</span> |
| 3252 | <pre>int lua_checkstack (lua_State *L, int | |
| 3123 | <pre>int lua_checkstack (lua_State *L, int extra);</pre> | |
| 3253 | 3124 | |
| 3254 | 3125 | <p> |
| 3255 | Ensures that the | |
| 3126 | Ensures that there are at least <code>extra</code> free stack slots in the stack. | |
| 3256 | 3127 | It returns false if it cannot fulfill the request, |
| 3257 | either because it would cause the stack | |
| 3258 | to be larger than a fixed maximum size | |
| 3259 | (typically at least several thousand elements) or | |
| 3260 | because it cannot allocate memory for the extra space. | |
| 3128 | because it would cause the stack to be larger than a fixed maximum size | |
| 3129 | (typically at least a few thousand elements) or | |
| 3130 | because it cannot allocate memory for the new stack size. | |
| 3261 | 3131 | This function never shrinks the stack; |
| 3262 | 3132 | if the stack is already larger than the new size, |
| 3263 | 3133 | it is left unchanged. |
| r242899 | r242900 | |
| 3278 | 3148 | because all resources are naturally released when the host program ends. |
| 3279 | 3149 | On the other hand, long-running programs that create multiple states, |
| 3280 | 3150 | such as daemons or web servers, |
| 3281 | ||
| 3151 | might need to close states as soon as they are not needed. | |
| 3282 | 3152 | |
| 3283 | 3153 | |
| 3284 | 3154 | |
| r242899 | r242900 | |
| 3295 | 3165 | following the semantics of the corresponding Lua operator |
| 3296 | 3166 | (that is, it may call metamethods). |
| 3297 | 3167 | Otherwise returns 0. |
| 3298 | Also returns 0 if any of the indices is no | |
| 3168 | Also returns 0 if any of the indices is non valid. | |
| 3299 | 3169 | |
| 3300 | 3170 | |
| 3301 | 3171 | <p> |
| r242899 | r242900 | |
| 3323 | 3193 | (that is, the function does nothing); |
| 3324 | 3194 | if <code>n</code> is 0, the result is the empty string. |
| 3325 | 3195 | Concatenation is performed following the usual semantics of Lua |
| 3326 | (see <a href="#3.4. | |
| 3196 | (see <a href="#3.4.5">§3.4.5</a>). | |
| 3327 | 3197 | |
| 3328 | 3198 | |
| 3329 | 3199 | |
| r242899 | r242900 | |
| 3334 | 3204 | <pre>void lua_copy (lua_State *L, int fromidx, int toidx);</pre> |
| 3335 | 3205 | |
| 3336 | 3206 | <p> |
| 3337 | Copies the element at index <code>fromidx</code> | |
| 3338 | into the valid index <code>toidx</code>, | |
| 3339 | replacing the value at that position. | |
| 3340 | Values at other positions are not affected. | |
| 3207 | Moves the element at index <code>fromidx</code> | |
| 3208 | into the valid index <code>toidx</code> | |
| 3209 | without shifting any element | |
| 3210 | (therefore replacing the value at that position). | |
| 3341 | 3211 | |
| 3342 | 3212 | |
| 3343 | 3213 | |
| r242899 | r242900 | |
| 3364 | 3234 | |
| 3365 | 3235 | <hr><h3><a name="lua_dump"><code>lua_dump</code></a></h3><p> |
| 3366 | 3236 | <span class="apii">[-0, +0, <em>e</em>]</span> |
| 3367 | <pre>int lua_dump (lua_State *L, | |
| 3368 | lua_Writer writer, | |
| 3369 | void *data, | |
| 3370 | int strip);</pre> | |
| 3237 | <pre>int lua_dump (lua_State *L, lua_Writer writer, void *data);</pre> | |
| 3371 | 3238 | |
| 3372 | 3239 | <p> |
| 3373 | 3240 | Dumps a function as a binary chunk. |
| r242899 | r242900 | |
| 3382 | 3249 | |
| 3383 | 3250 | |
| 3384 | 3251 | <p> |
| 3385 | If <code>strip</code> is true, | |
| 3386 | the binary representation is created without debug information | |
| 3387 | about the function. | |
| 3388 | ||
| 3389 | ||
| 3390 | <p> | |
| 3391 | 3252 | The value returned is the error code returned by the last |
| 3392 | 3253 | call to the writer; |
| 3393 | 3254 | 0 means no errors. |
| r242899 | r242900 | |
| 3405 | 3266 | <pre>int lua_error (lua_State *L);</pre> |
| 3406 | 3267 | |
| 3407 | 3268 | <p> |
| 3408 | Generates a Lua error, | |
| 3409 | using the value at the top of the stack as the error object. | |
| 3269 | Generates a Lua error. | |
| 3270 | The error message (which can actually be a Lua value of any type) | |
| 3271 | must be on the stack top. | |
| 3410 | 3272 | This function does a long jump, |
| 3411 | 3273 | and therefore never returns |
| 3412 | 3274 | (see <a href="#luaL_error"><code>luaL_error</code></a>). |
| r242899 | r242900 | |
| 3452 | 3314 | |
| 3453 | 3315 | <li><b><code>LUA_GCSTEP</code>: </b> |
| 3454 | 3316 | performs an incremental step of garbage collection. |
| 3317 | The step "size" is controlled by <code>data</code> | |
| 3318 | (larger values mean more steps) in a non-specified way. | |
| 3319 | If you want to control the step size | |
| 3320 | you must experimentally tune the value of <code>data</code>. | |
| 3321 | The function returns 1 if the step finished a | |
| 3322 | garbage-collection cycle. | |
| 3455 | 3323 | </li> |
| 3456 | 3324 | |
| 3457 | 3325 | <li><b><code>LUA_GCSETPAUSE</code>: </b> |
| 3458 | 3326 | sets <code>data</code> as the new value |
| 3459 | for the <em>pause</em> of the collector (see <a href="#2.5">§2.5</a>) | |
| 3460 | and returns the previous value of the pause. | |
| 3327 | for the <em>pause</em> of the collector (see <a href="#2.5">§2.5</a>). | |
| 3328 | The function returns the previous value of the pause. | |
| 3461 | 3329 | </li> |
| 3462 | 3330 | |
| 3463 | 3331 | <li><b><code>LUA_GCSETSTEPMUL</code>: </b> |
| 3464 | 3332 | sets <code>data</code> as the new value for the <em>step multiplier</em> of |
| 3465 | the collector (see <a href="#2.5">§2.5</a>) | |
| 3466 | and returns the previous value of the step multiplier. | |
| 3333 | the collector (see <a href="#2.5">§2.5</a>). | |
| 3334 | The function returns the previous value of the step multiplier. | |
| 3467 | 3335 | </li> |
| 3468 | 3336 | |
| 3469 | 3337 | <li><b><code>LUA_GCISRUNNING</code>: </b> |
| r242899 | r242900 | |
| 3471 | 3339 | (i.e., not stopped). |
| 3472 | 3340 | </li> |
| 3473 | 3341 | |
| 3342 | <li><b><code>LUA_GCGEN</code>: </b> | |
| 3343 | changes the collector to generational mode | |
| 3344 | (see <a href="#2.5">§2.5</a>). | |
| 3345 | </li> | |
| 3346 | ||
| 3347 | <li><b><code>LUA_GCINC</code>: </b> | |
| 3348 | changes the collector to incremental mode. | |
| 3349 | This is the default mode. | |
| 3350 | </li> | |
| 3351 | ||
| 3474 | 3352 | </ul> |
| 3475 | 3353 | |
| 3476 | 3354 | <p> |
| r242899 | r242900 | |
| 3488 | 3366 | <p> |
| 3489 | 3367 | Returns the memory-allocation function of a given state. |
| 3490 | 3368 | If <code>ud</code> is not <code>NULL</code>, Lua stores in <code>*ud</code> the |
| 3491 | opaque pointer | |
| 3369 | opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>. | |
| 3492 | 3370 | |
| 3493 | 3371 | |
| 3494 | 3372 | |
| 3495 | 3373 | |
| 3496 | 3374 | |
| 3497 | <hr><h3><a name="lua_getfield"><code>lua_getfield</code></a></h3><p> | |
| 3498 | <span class="apii">[-0, +1, <em>e</em>]</span> | |
| 3499 | <pre>int lua_getfield (lua_State *L, int index, const char *k);</pre> | |
| 3500 | ||
| 3501 | <p> | |
| 3502 | Pushes onto the stack the value <code>t[k]</code>, | |
| 3503 | where <code>t</code> is the value at the given index. | |
| 3504 | As in Lua, this function may trigger a metamethod | |
| 3505 | for the "index" event (see <a href="#2.4">§2.4</a>). | |
| 3506 | ||
| 3507 | ||
| 3508 | <p> | |
| 3509 | Returns the type of the pushed value. | |
| 3510 | ||
| 3511 | ||
| 3512 | ||
| 3513 | ||
| 3514 | ||
| 3515 | <hr><h3><a name="lua_getextraspace"><code>lua_getextraspace</code></a></h3><p> | |
| 3375 | <hr><h3><a name="lua_getctx"><code>lua_getctx</code></a></h3><p> | |
| 3516 | 3376 | <span class="apii">[-0, +0, –]</span> |
| 3517 | <pre> | |
| 3377 | <pre>int lua_getctx (lua_State *L, int *ctx);</pre> | |
| 3518 | 3378 | |
| 3519 | 3379 | <p> |
| 3520 | Returns a pointer to a raw memory area associated with the | |
| 3521 | given Lua state. | |
| 3522 | The application can use this area for any purpose; | |
| 3523 | Lua does not use it for anything. | |
| 3380 | This function is called by a continuation function (see <a href="#4.7">§4.7</a>) | |
| 3381 | to retrieve the status of the thread and a context information. | |
| 3524 | 3382 | |
| 3525 | 3383 | |
| 3526 | 3384 | <p> |
| 3527 | Each new thread has this area initialized with a copy | |
| 3528 | of the area of the main thread. | |
| 3385 | When called in the original function, | |
| 3386 | <a href="#lua_getctx"><code>lua_getctx</code></a> always returns <a href="#pdf-LUA_OK"><code>LUA_OK</code></a> | |
| 3387 | and does not change the value of its argument <code>ctx</code>. | |
| 3388 | When called inside a continuation function, | |
| 3389 | <a href="#lua_getctx"><code>lua_getctx</code></a> returns <a href="#pdf-LUA_YIELD"><code>LUA_YIELD</code></a> and sets | |
| 3390 | the value of <code>ctx</code> to be the context information | |
| 3391 | (the value passed as the <code>ctx</code> argument | |
| 3392 | to the callee together with the continuation function). | |
| 3529 | 3393 | |
| 3530 | 3394 | |
| 3531 | 3395 | <p> |
| 3532 | By default, this area has the size of a pointer to void, | |
| 3533 | but you can recompile Lua with a different size for this area. | |
| 3534 | (See <code>LUA_EXTRASPACE</code> in <code>luaconf.h</code>.) | |
| 3396 | When the callee is <a href="#lua_pcallk"><code>lua_pcallk</code></a>, | |
| 3397 | Lua may also call its continuation function | |
| 3398 | to handle errors during the call. | |
| 3399 | That is, upon an error in the function called by <a href="#lua_pcallk"><code>lua_pcallk</code></a>, | |
| 3400 | Lua may not return to the original function | |
| 3401 | but instead may call the continuation function. | |
| 3402 | In that case, a call to <a href="#lua_getctx"><code>lua_getctx</code></a> will return the error code | |
| 3403 | (the value that would be returned by <a href="#lua_pcallk"><code>lua_pcallk</code></a>); | |
| 3404 | the value of <code>ctx</code> will be set to the context information, | |
| 3405 | as in the case of a yield. | |
| 3535 | 3406 | |
| 3536 | 3407 | |
| 3537 | 3408 | |
| 3538 | 3409 | |
| 3539 | 3410 | |
| 3540 | <hr><h3><a name="lua_get | |
| 3411 | <hr><h3><a name="lua_getfield"><code>lua_getfield</code></a></h3><p> | |
| 3541 | 3412 | <span class="apii">[-0, +1, <em>e</em>]</span> |
| 3542 | <pre>i | |
| 3413 | <pre>void lua_getfield (lua_State *L, int index, const char *k);</pre> | |
| 3543 | 3414 | |
| 3544 | 3415 | <p> |
| 3545 | Pushes onto the stack the value of the global <code>name</code>. | |
| 3546 | Returns the type of that value. | |
| 3416 | Pushes onto the stack the value <code>t[k]</code>, | |
| 3417 | where <code>t</code> is the value at the given index. | |
| 3418 | As in Lua, this function may trigger a metamethod | |
| 3419 | for the "index" event (see <a href="#2.4">§2.4</a>). | |
| 3547 | 3420 | |
| 3548 | 3421 | |
| 3549 | 3422 | |
| 3550 | 3423 | |
| 3551 | 3424 | |
| 3552 | <hr><h3><a name="lua_get | |
| 3425 | <hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p> | |
| 3553 | 3426 | <span class="apii">[-0, +1, <em>e</em>]</span> |
| 3554 | <pre>i | |
| 3427 | <pre>void lua_getglobal (lua_State *L, const char *name);</pre> | |
| 3555 | 3428 | |
| 3556 | 3429 | <p> |
| 3557 | Pushes onto the stack the value <code>t[i]</code>, | |
| 3558 | where <code>t</code> is the value at the given index. | |
| 3559 | As in Lua, this function may trigger a metamethod | |
| 3560 | for the "index" event (see <a href="#2.4">§2.4</a>). | |
| 3430 | Pushes onto the stack the value of the global <code>name</code>. | |
| 3561 | 3431 | |
| 3562 | 3432 | |
| 3563 | <p> | |
| 3564 | Returns the type of the pushed value. | |
| 3565 | 3433 | |
| 3566 | 3434 | |
| 3567 | 3435 | |
| 3568 | ||
| 3569 | ||
| 3570 | 3436 | <hr><h3><a name="lua_getmetatable"><code>lua_getmetatable</code></a></h3><p> |
| 3571 | 3437 | <span class="apii">[-0, +(0|1), –]</span> |
| 3572 | 3438 | <pre>int lua_getmetatable (lua_State *L, int index);</pre> |
| 3573 | 3439 | |
| 3574 | 3440 | <p> |
| 3575 | If the value at the given index has a metatable, | |
| 3576 | the function pushes that metatable onto the stack and returns 1. | |
| 3577 | Otherwise, | |
| 3441 | Pushes onto the stack the metatable of the value at the given index. | |
| 3442 | If the value does not have a metatable, | |
| 3578 | 3443 | the function returns 0 and pushes nothing on the stack. |
| 3579 | 3444 | |
| 3580 | 3445 | |
| r242899 | r242900 | |
| 3583 | 3448 | |
| 3584 | 3449 | <hr><h3><a name="lua_gettable"><code>lua_gettable</code></a></h3><p> |
| 3585 | 3450 | <span class="apii">[-1, +1, <em>e</em>]</span> |
| 3586 | <pre>i | |
| 3451 | <pre>void lua_gettable (lua_State *L, int index);</pre> | |
| 3587 | 3452 | |
| 3588 | 3453 | <p> |
| 3589 | 3454 | Pushes onto the stack the value <code>t[k]</code>, |
| r242899 | r242900 | |
| 3592 | 3457 | |
| 3593 | 3458 | |
| 3594 | 3459 | <p> |
| 3595 | This function pops the key from the stack, | |
| 3596 | pushing the resulting value in its place. | |
| 3460 | This function pops the key from the stack | |
| 3461 | (putting the resulting value in its place). | |
| 3597 | 3462 | As in Lua, this function may trigger a metamethod |
| 3598 | 3463 | for the "index" event (see <a href="#2.4">§2.4</a>). |
| 3599 | 3464 | |
| 3600 | 3465 | |
| 3601 | <p> | |
| 3602 | Returns the type of the pushed value. | |
| 3603 | 3466 | |
| 3604 | 3467 | |
| 3605 | 3468 | |
| 3606 | ||
| 3607 | ||
| 3608 | 3469 | <hr><h3><a name="lua_gettop"><code>lua_gettop</code></a></h3><p> |
| 3609 | 3470 | <span class="apii">[-0, +0, –]</span> |
| 3610 | 3471 | <pre>int lua_gettop (lua_State *L);</pre> |
| r242899 | r242900 | |
| 3612 | 3473 | <p> |
| 3613 | 3474 | Returns the index of the top element in the stack. |
| 3614 | 3475 | Because indices start at 1, |
| 3615 | this result is equal to the number of elements in the stack; | |
| 3616 | in particular, 0 means an empty stack. | |
| 3476 | this result is equal to the number of elements in the stack | |
| 3477 | (and so 0 means an empty stack). | |
| 3617 | 3478 | |
| 3618 | 3479 | |
| 3619 | 3480 | |
| r242899 | r242900 | |
| 3621 | 3482 | |
| 3622 | 3483 | <hr><h3><a name="lua_getuservalue"><code>lua_getuservalue</code></a></h3><p> |
| 3623 | 3484 | <span class="apii">[-0, +1, –]</span> |
| 3624 | <pre>i | |
| 3485 | <pre>void lua_getuservalue (lua_State *L, int index);</pre> | |
| 3625 | 3486 | |
| 3626 | 3487 | <p> |
| 3627 | 3488 | Pushes onto the stack the Lua value associated with the userdata |
| 3628 | 3489 | at the given index. |
| 3490 | This Lua value must be a table or <b>nil</b>. | |
| 3629 | 3491 | |
| 3630 | 3492 | |
| 3631 | <p> | |
| 3632 | Returns the type of the pushed value. | |
| 3633 | 3493 | |
| 3634 | 3494 | |
| 3635 | 3495 | |
| 3636 | ||
| 3637 | ||
| 3638 | 3496 | <hr><h3><a name="lua_insert"><code>lua_insert</code></a></h3><p> |
| 3639 | 3497 | <span class="apii">[-1, +1, –]</span> |
| 3640 | 3498 | <pre>void lua_insert (lua_State *L, int index);</pre> |
| r242899 | r242900 | |
| 3650 | 3508 | |
| 3651 | 3509 | |
| 3652 | 3510 | <hr><h3><a name="lua_Integer"><code>lua_Integer</code></a></h3> |
| 3653 | <pre>typedef | |
| 3511 | <pre>typedef ptrdiff_t lua_Integer;</pre> | |
| 3654 | 3512 | |
| 3655 | 3513 | <p> |
| 3656 | The type | |
| 3514 | The type used by the Lua API to represent signed integral values. | |
| 3657 | 3515 | |
| 3658 | 3516 | |
| 3659 | 3517 | <p> |
| 3660 | By default this type is <code>long long</code>, | |
| 3661 | (usually a 64-bit two-complement integer), | |
| 3662 | but that can be changed to <code>long</code> or <code>int</code> | |
| 3663 | (usually a 32-bit two-complement integer). | |
| 3664 | (See <code>LUA_INT</code> in <code>luaconf.h</code>.) | |
| 3518 | By default it is a <code>ptrdiff_t</code>, | |
| 3519 | which is usually the largest signed integral type the machine handles | |
| 3520 | "comfortably". | |
| 3665 | 3521 | |
| 3666 | 3522 | |
| 3667 | <p> | |
| 3668 | Lua also defines the constants | |
| 3669 | <a name="pdf-LUA_MININTEGER"><code>LUA_MININTEGER</code></a> and <a name="pdf-LUA_MAXINTEGER"><code>LUA_MAXINTEGER</code></a>, | |
| 3670 | with the minimum and the maximum values that fit in this type. | |
| 3671 | 3523 | |
| 3672 | 3524 | |
| 3673 | 3525 | |
| 3674 | ||
| 3675 | ||
| 3676 | 3526 | <hr><h3><a name="lua_isboolean"><code>lua_isboolean</code></a></h3><p> |
| 3677 | 3527 | <span class="apii">[-0, +0, –]</span> |
| 3678 | 3528 | <pre>int lua_isboolean (lua_State *L, int index);</pre> |
| r242899 | r242900 | |
| 3709 | 3559 | |
| 3710 | 3560 | |
| 3711 | 3561 | |
| 3712 | <hr><h3><a name="lua_isinteger"><code>lua_isinteger</code></a></h3><p> | |
| 3713 | <span class="apii">[-0, +0, –]</span> | |
| 3714 | <pre>int lua_isinteger (lua_State *L, int index);</pre> | |
| 3715 | ||
| 3716 | <p> | |
| 3717 | Returns 1 if the value at the given index is an integer | |
| 3718 | (that is, the value is a number and is represented as an integer), | |
| 3719 | and 0 otherwise. | |
| 3720 | ||
| 3721 | ||
| 3722 | ||
| 3723 | ||
| 3724 | ||
| 3725 | 3562 | <hr><h3><a name="lua_islightuserdata"><code>lua_islightuserdata</code></a></h3><p> |
| 3726 | 3563 | <span class="apii">[-0, +0, –]</span> |
| 3727 | 3564 | <pre>int lua_islightuserdata (lua_State *L, int index);</pre> |
| r242899 | r242900 | |
| 3833 | 3670 | |
| 3834 | 3671 | |
| 3835 | 3672 | |
| 3836 | <hr><h3><a name="lua_isyieldable"><code>lua_isyieldable</code></a></h3><p> | |
| 3837 | <span class="apii">[-0, +0, –]</span> | |
| 3838 | <pre>int lua_isyieldable (lua_State *L);</pre> | |
| 3839 | ||
| 3840 | <p> | |
| 3841 | Returns 1 if the given coroutine can yield, | |
| 3842 | and 0 otherwise. | |
| 3843 | ||
| 3844 | ||
| 3845 | ||
| 3846 | ||
| 3847 | ||
| 3848 | <hr><h3><a name="lua_KContext"><code>lua_KContext</code></a></h3> | |
| 3849 | <pre>typedef ... lua_KContext;</pre> | |
| 3850 | ||
| 3851 | <p> | |
| 3852 | The type for continuation-function contexts. | |
| 3853 | It must be a numerical type. | |
| 3854 | This type is defined as <code>intptr_t</code> | |
| 3855 | when <code>intptr_t</code> is available, | |
| 3856 | so that it can store pointers too. | |
| 3857 | Otherwise, it is defined as <code>ptrdiff_t</code>. | |
| 3858 | ||
| 3859 | ||
| 3860 | ||
| 3861 | ||
| 3862 | ||
| 3863 | <hr><h3><a name="lua_KFunction"><code>lua_KFunction</code></a></h3> | |
| 3864 | <pre>typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);</pre> | |
| 3865 | ||
| 3866 | <p> | |
| 3867 | Type for continuation functions (see <a href="#4.7">§4.7</a>). | |
| 3868 | ||
| 3869 | ||
| 3870 | ||
| 3871 | ||
| 3872 | ||
| 3873 | 3673 | <hr><h3><a name="lua_len"><code>lua_len</code></a></h3><p> |
| 3874 | 3674 | <span class="apii">[-0, +1, <em>e</em>]</span> |
| 3875 | 3675 | <pre>void lua_len (lua_State *L, int index);</pre> |
| 3876 | 3676 | |
| 3877 | 3677 | <p> |
| 3878 | Returns the length of the value at the given index. | |
| 3879 | It is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.7">§3.4.7</a>) and | |
| 3880 | may trigger a metamethod for the "length" event (see <a href="#2.4">§2.4</a>). | |
| 3678 | Returns the "length" of the value at the given index; | |
| 3679 | it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">§3.4.6</a>). | |
| 3881 | 3680 | The result is pushed on the stack. |
| 3882 | 3681 | |
| 3883 | 3682 | |
| r242899 | r242900 | |
| 3889 | 3688 | <pre>int lua_load (lua_State *L, |
| 3890 | 3689 | lua_Reader reader, |
| 3891 | 3690 | void *data, |
| 3892 | const char * | |
| 3691 | const char *source, | |
| 3893 | 3692 | const char *mode);</pre> |
| 3894 | 3693 | |
| 3895 | 3694 | <p> |
| 3896 | Loads a Lua chunk without running it. | |
| 3695 | Loads a Lua chunk (without running it). | |
| 3897 | 3696 | If there are no errors, |
| 3898 | 3697 | <code>lua_load</code> pushes the compiled chunk as a Lua |
| 3899 | 3698 | function on top of the stack. |
| r242899 | r242900 | |
| 3928 | 3727 | |
| 3929 | 3728 | |
| 3930 | 3729 | <p> |
| 3931 | The <code> | |
| 3730 | The <code>source</code> argument gives a name to the chunk, | |
| 3932 | 3731 | which is used for error messages and in debug information (see <a href="#4.9">§4.9</a>). |
| 3933 | 3732 | |
| 3934 | 3733 | |
| r242899 | r242900 | |
| 3942 | 3741 | |
| 3943 | 3742 | <p> |
| 3944 | 3743 | <code>lua_load</code> uses the stack internally, |
| 3945 | so the reader function | |
| 3744 | so the reader function should always leave the stack | |
| 3946 | 3745 | unmodified when returning. |
| 3947 | 3746 | |
| 3948 | 3747 | |
| 3949 | 3748 | <p> |
| 3950 | If the resulting function has upvalues, | |
| 3951 | its first upvalue is set to the value of the global environment | |
| 3749 | If the resulting function has one upvalue, | |
| 3750 | this upvalue is set to the value of the global environment | |
| 3952 | 3751 | stored at index <code>LUA_RIDX_GLOBALS</code> in the registry (see <a href="#4.5">§4.5</a>). |
| 3953 | 3752 | When loading main chunks, |
| 3954 | 3753 | this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>). |
| 3955 | Other upvalues are initialized with <b>nil</b>. | |
| 3956 | 3754 | |
| 3957 | 3755 | |
| 3958 | 3756 | |
| r242899 | r242900 | |
| 3964 | 3762 | |
| 3965 | 3763 | <p> |
| 3966 | 3764 | Creates a new thread running in a new, independent state. |
| 3967 | Returns <code>NULL</code> if | |
| 3765 | Returns <code>NULL</code> if cannot create the thread or the state | |
| 3968 | 3766 | (due to lack of memory). |
| 3969 | 3767 | The argument <code>f</code> is the allocator function; |
| 3970 | 3768 | Lua does all memory allocation for this state through this function. |
| r242899 | r242900 | |
| 4071 | 3869 | <pre>typedef double lua_Number;</pre> |
| 4072 | 3870 | |
| 4073 | 3871 | <p> |
| 4074 | The type of floats in Lua. | |
| 3872 | The type of numbers in Lua. | |
| 3873 | By default, it is double, but that can be changed in <code>luaconf.h</code>. | |
| 3874 | Through this configuration file you can change | |
| 3875 | Lua to operate with another type for numbers (e.g., float or long). | |
| 4075 | 3876 | |
| 4076 | 3877 | |
| 4077 | <p> | |
| 4078 | By default this type is double, | |
| 4079 | but that can be changed to a single float. | |
| 4080 | (See <code>LUA_REAL</code> in <code>luaconf.h</code>.) | |
| 4081 | 3878 | |
| 4082 | 3879 | |
| 4083 | 3880 | |
| 4084 | ||
| 4085 | ||
| 4086 | <hr><h3><a name="lua_numbertointeger"><code>lua_numbertointeger</code></a></h3> | |
| 4087 | <pre>int lua_numbertointeger (lua_Number n, lua_Integer *p);</pre> | |
| 4088 | ||
| 4089 | <p> | |
| 4090 | Converts a Lua float to a Lua integer. | |
| 4091 | This macro assumes that <code>n</code> has an integral value. | |
| 4092 | If that value is within the range of Lua integers, | |
| 4093 | it is converted to an integer and assigned to <code>*p</code>. | |
| 4094 | The macro results in a boolean indicating whether the | |
| 4095 | conversion was successful. | |
| 4096 | (Note that this range test can be tricky to do | |
| 4097 | correctly without this macro, | |
| 4098 | due to roundings.) | |
| 4099 | ||
| 4100 | ||
| 4101 | <p> | |
| 4102 | This macro may evaluate its arguments more than once. | |
| 4103 | ||
| 4104 | ||
| 4105 | ||
| 4106 | ||
| 4107 | ||
| 4108 | 3881 | <hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p> |
| 4109 | 3882 | <span class="apii">[-(nargs + 1), +(nresults|1), –]</span> |
| 4110 | 3883 | <pre>int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);</pre> |
| r242899 | r242900 | |
| 4148 | 3921 | |
| 4149 | 3922 | |
| 4150 | 3923 | <p> |
| 4151 | The <a href="#lua_pcall"><code>lua_pcall</code></a> function returns one of the following co | |
| 3924 | The <a href="#lua_pcall"><code>lua_pcall</code></a> function returns one of the following codes | |
| 4152 | 3925 | (defined in <code>lua.h</code>): |
| 4153 | 3926 | |
| 4154 | 3927 | <ul> |
| r242899 | r242900 | |
| 4171 | 3944 | |
| 4172 | 3945 | <li><b><a name="pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>: </b> |
| 4173 | 3946 | error while running a <code>__gc</code> metamethod. |
| 4174 | (This error typically has no relation with the function being called.) | |
| 3947 | (This error typically has no relation with the function being called. | |
| 3948 | It is generated by the garbage collector.) | |
| 4175 | 3949 | </li> |
| 4176 | 3950 | |
| 4177 | 3951 | </ul> |
| r242899 | r242900 | |
| 4184 | 3958 | <pre>int lua_pcallk (lua_State *L, |
| 4185 | 3959 | int nargs, |
| 4186 | 3960 | int nresults, |
| 4187 | int msgh, | |
| 4188 | lua_KContext ctx, | |
| 4189 | lua_KFunction k);</pre> | |
| 3961 | int errfunc, | |
| 3962 | int ctx, | |
| 3963 | lua_CFunction k);</pre> | |
| 4190 | 3964 | |
| 4191 | 3965 | <p> |
| 4192 | 3966 | This function behaves exactly like <a href="#lua_pcall"><code>lua_pcall</code></a>, |
| r242899 | r242900 | |
| 4232 | 4006 | thus creating a C closure (see <a href="#4.4">§4.4</a>); |
| 4233 | 4007 | these values are then accessible to the function whenever it is called. |
| 4234 | 4008 | To associate values with a C function, |
| 4235 | first these values | |
| 4009 | first these values should be pushed onto the stack | |
| 4236 | 4010 | (when there are multiple values, the first value is pushed first). |
| 4237 | 4011 | Then <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> |
| 4238 | 4012 | is called to create and push the C function onto the stack, |
| 4239 | with the argument <code>n</code> telling how many values | |
| 4013 | with the argument <code>n</code> telling how many values should be | |
| 4240 | 4014 | associated with the function. |
| 4241 | 4015 | <a href="#lua_pushcclosure"><code>lua_pushcclosure</code></a> also pops these values from the stack. |
| 4242 | 4016 | |
| r242899 | r242900 | |
| 4249 | 4023 | When <code>n</code> is zero, |
| 4250 | 4024 | this function creates a <em>light C function</em>, |
| 4251 | 4025 | which is just a pointer to the C function. |
| 4252 | In that case, it never r | |
| 4026 | In that case, it never throws a memory error. | |
| 4253 | 4027 | |
| 4254 | 4028 | |
| 4255 | 4029 | |
| r242899 | r242900 | |
| 4291 | 4065 | <p> |
| 4292 | 4066 | Pushes onto the stack a formatted string |
| 4293 | 4067 | and returns a pointer to this string. |
| 4294 | It is similar to the | |
| 4068 | It is similar to the ANSI C function <code>sprintf</code>, | |
| 4295 | 4069 | but has some important differences: |
| 4296 | 4070 | |
| 4297 | 4071 | <ul> |
| r242899 | r242900 | |
| 4306 | 4080 | The conversion specifiers are quite restricted. |
| 4307 | 4081 | There are no flags, widths, or precisions. |
| 4308 | 4082 | The conversion specifiers can only be |
| 4309 | '<code>%%</code>' (inserts | |
| 4083 | '<code>%%</code>' (inserts a '<code>%</code>' in the string), | |
| 4310 | 4084 | '<code>%s</code>' (inserts a zero-terminated string, with no size restrictions), |
| 4311 | 4085 | '<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>), |
| 4312 | '<code>%L</code>' (inserts a <a href="#lua_Integer"><code>lua_Integer</code></a>), | |
| 4313 | 4086 | '<code>%p</code>' (inserts a pointer as a hexadecimal numeral), |
| 4314 | '<code>%d</code>' (inserts an <code>int</code>), | |
| 4315 | '<code>%c</code>' (inserts an <code>int</code> as a one-byte character), and | |
| 4316 | '<code>%U</code>' (inserts a <code>long int</code> as a UTF-8 byte sequence). | |
| 4087 | '<code>%d</code>' (inserts an <code>int</code>), and | |
| 4088 | '<code>%c</code>' (inserts an <code>int</code> as a byte). | |
| 4317 | 4089 | </li> |
| 4318 | 4090 | |
| 4319 | 4091 | </ul> |
| r242899 | r242900 | |
| 4337 | 4109 | <pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre> |
| 4338 | 4110 | |
| 4339 | 4111 | <p> |
| 4340 | Pushes a | |
| 4112 | Pushes a number with value <code>n</code> onto the stack. | |
| 4341 | 4113 | |
| 4342 | 4114 | |
| 4343 | 4115 | |
| r242899 | r242900 | |
| 4414 | 4186 | <pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre> |
| 4415 | 4187 | |
| 4416 | 4188 | <p> |
| 4417 | Pushes a | |
| 4189 | Pushes a number with value <code>n</code> onto the stack. | |
| 4418 | 4190 | |
| 4419 | 4191 | |
| 4420 | 4192 | |
| r242899 | r242900 | |
| 4455 | 4227 | |
| 4456 | 4228 | |
| 4457 | 4229 | |
| 4230 | <hr><h3><a name="lua_pushunsigned"><code>lua_pushunsigned</code></a></h3><p> | |
| 4231 | <span class="apii">[-0, +1, –]</span> | |
| 4232 | <pre>void lua_pushunsigned (lua_State *L, lua_Unsigned n);</pre> | |
| 4233 | ||
| 4234 | <p> | |
| 4235 | Pushes a number with value <code>n</code> onto the stack. | |
| 4236 | ||
| 4237 | ||
| 4238 | ||
| 4239 | ||
| 4240 | ||
| 4458 | 4241 | <hr><h3><a name="lua_pushvalue"><code>lua_pushvalue</code></a></h3><p> |
| 4459 | 4242 | <span class="apii">[-0, +1, –]</span> |
| 4460 | 4243 | <pre>void lua_pushvalue (lua_State *L, int index);</pre> |
| r242899 | r242900 | |
| 4490 | 4273 | <code>index2</code> are primitively equal |
| 4491 | 4274 | (that is, without calling metamethods). |
| 4492 | 4275 | Otherwise returns 0. |
| 4493 | Also returns 0 if any of the indices are no | |
| 4276 | Also returns 0 if any of the indices are non valid. | |
| 4494 | 4277 | |
| 4495 | 4278 | |
| 4496 | 4279 | |
| r242899 | r242900 | |
| 4498 | 4281 | |
| 4499 | 4282 | <hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p> |
| 4500 | 4283 | <span class="apii">[-1, +1, –]</span> |
| 4501 | <pre>i | |
| 4284 | <pre>void lua_rawget (lua_State *L, int index);</pre> | |
| 4502 | 4285 | |
| 4503 | 4286 | <p> |
| 4504 | 4287 | Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw access |
| r242899 | r242900 | |
| 4510 | 4293 | |
| 4511 | 4294 | <hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p> |
| 4512 | 4295 | <span class="apii">[-0, +1, –]</span> |
| 4513 | <pre>i | |
| 4296 | <pre>void lua_rawgeti (lua_State *L, int index, int n);</pre> | |
| 4514 | 4297 | |
| 4515 | 4298 | <p> |
| 4516 | 4299 | Pushes onto the stack the value <code>t[n]</code>, |
| r242899 | r242900 | |
| 4519 | 4302 | that is, it does not invoke metamethods. |
| 4520 | 4303 | |
| 4521 | 4304 | |
| 4522 | <p> | |
| 4523 | Returns the type of the pushed value. | |
| 4524 | 4305 | |
| 4525 | 4306 | |
| 4526 | 4307 | |
| 4527 | ||
| 4528 | ||
| 4529 | 4308 | <hr><h3><a name="lua_rawgetp"><code>lua_rawgetp</code></a></h3><p> |
| 4530 | 4309 | <span class="apii">[-0, +1, –]</span> |
| 4531 | <pre>i | |
| 4310 | <pre>void lua_rawgetp (lua_State *L, int index, const void *p);</pre> | |
| 4532 | 4311 | |
| 4533 | 4312 | <p> |
| 4534 | 4313 | Pushes onto the stack the value <code>t[k]</code>, |
| r242899 | r242900 | |
| 4538 | 4317 | that is, it does not invoke metamethods. |
| 4539 | 4318 | |
| 4540 | 4319 | |
| 4541 | <p> | |
| 4542 | Returns the type of the pushed value. | |
| 4543 | 4320 | |
| 4544 | 4321 | |
| 4545 | 4322 | |
| 4546 | ||
| 4547 | ||
| 4548 | 4323 | <hr><h3><a name="lua_rawlen"><code>lua_rawlen</code></a></h3><p> |
| 4549 | 4324 | <span class="apii">[-0, +0, –]</span> |
| 4550 | 4325 | <pre>size_t lua_rawlen (lua_State *L, int index);</pre> |
| r242899 | r242900 | |
| 4576 | 4351 | |
| 4577 | 4352 | <hr><h3><a name="lua_rawseti"><code>lua_rawseti</code></a></h3><p> |
| 4578 | 4353 | <span class="apii">[-1, +0, <em>e</em>]</span> |
| 4579 | <pre>void lua_rawseti (lua_State *L, int index, | |
| 4354 | <pre>void lua_rawseti (lua_State *L, int index, int n);</pre> | |
| 4580 | 4355 | |
| 4581 | 4356 | <p> |
| 4582 | Does the equivalent of <code>t[ | |
| 4357 | Does the equivalent of <code>t[n] = v</code>, | |
| 4583 | 4358 | where <code>t</code> is the table at the given index |
| 4584 | 4359 | and <code>v</code> is the value at the top of the stack. |
| 4585 | 4360 | |
| r242899 | r242900 | |
| 4726 | 4501 | |
| 4727 | 4502 | |
| 4728 | 4503 | |
| 4729 | <hr><h3><a name="lua_rotate"><code>lua_rotate</code></a></h3><p> | |
| 4730 | <span class="apii">[-0, +0, –]</span> | |
| 4731 | <pre>void lua_rotate (lua_State *L, int idx, int n);</pre> | |
| 4732 | ||
| 4733 | <p> | |
| 4734 | Rotates the stack elements from <code>idx</code> to the top <code>n</code> positions | |
| 4735 | in the direction of the top, for a positive <code>n</code>, | |
| 4736 | or <code>-n</code> positions in the direction of the bottom, | |
| 4737 | for a negative <code>n</code>. | |
| 4738 | The absolute value of <code>n</code> must not be greater than the size | |
| 4739 | of the slice being rotated. | |
| 4740 | ||
| 4741 | ||
| 4742 | ||
| 4743 | ||
| 4744 | ||
| 4745 | 4504 | <hr><h3><a name="lua_setallocf"><code>lua_setallocf</code></a></h3><p> |
| 4746 | 4505 | <span class="apii">[-0, +0, –]</span> |
| 4747 | 4506 | <pre>void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);</pre> |
| r242899 | r242900 | |
| 4785 | 4544 | |
| 4786 | 4545 | |
| 4787 | 4546 | |
| 4788 | <hr><h3><a name="lua_seti"><code>lua_seti</code></a></h3><p> | |
| 4789 | <span class="apii">[-1, +0, <em>e</em>]</span> | |
| 4790 | <pre>void lua_seti (lua_State *L, int index, lua_Integer n);</pre> | |
| 4791 | ||
| 4792 | <p> | |
| 4793 | Does the equivalent to <code>t[n] = v</code>, | |
| 4794 | where <code>t</code> is the value at the given index | |
| 4795 | and <code>v</code> is the value at the top of the stack. | |
| 4796 | ||
| 4797 | ||
| 4798 | <p> | |
| 4799 | This function pops the value from the stack. | |
| 4800 | As in Lua, this function may trigger a metamethod | |
| 4801 | for the "newindex" event (see <a href="#2.4">§2.4</a>). | |
| 4802 | ||
| 4803 | ||
| 4804 | ||
| 4805 | ||
| 4806 | ||
| 4807 | 4547 | <hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p> |
| 4808 | 4548 | <span class="apii">[-1, +0, –]</span> |
| 4809 | 4549 | <pre>void lua_setmetatable (lua_State *L, int index);</pre> |
| r242899 | r242900 | |
| 4856 | 4596 | <pre>void lua_setuservalue (lua_State *L, int index);</pre> |
| 4857 | 4597 | |
| 4858 | 4598 | <p> |
| 4859 | Pops a | |
| 4599 | Pops a table or <b>nil</b> from the stack and sets it as | |
| 4860 | 4600 | the new value associated to the userdata at the given index. |
| 4861 | 4601 | |
| 4862 | 4602 | |
| r242899 | r242900 | |
| 4908 | 4648 | |
| 4909 | 4649 | |
| 4910 | 4650 | |
| 4911 | <hr><h3><a name="lua_stringtonumber"><code>lua_stringtonumber</code></a></h3><p> | |
| 4912 | <span class="apii">[-0, +1, –]</span> | |
| 4913 | <pre>size_t lua_stringtonumber (lua_State *L, const char *s);</pre> | |
| 4914 | ||
| 4915 | <p> | |
| 4916 | Converts the zero-terminated string <code>s</code> to a number, | |
| 4917 | pushes that number into the stack, | |
| 4918 | and returns the total size of the string, | |
| 4919 | that is, its length plus one. | |
| 4920 | The conversion can result in an integer or a float, | |
| 4921 | according to the lexical conventions of Lua (see <a href="#3.1">§3.1</a>). | |
| 4922 | The string may have leading and trailing spaces and a sign. | |
| 4923 | If the string is not a valid numeral, | |
| 4924 | returns 0 and pushes nothing. | |
| 4925 | (Note that the result can be used as a boolean, | |
| 4926 | true if the conversion succeeds.) | |
| 4927 | ||
| 4928 | ||
| 4929 | ||
| 4930 | ||
| 4931 | ||
| 4932 | 4651 | <hr><h3><a name="lua_toboolean"><code>lua_toboolean</code></a></h3><p> |
| 4933 | 4652 | <span class="apii">[-0, +0, –]</span> |
| 4934 | 4653 | <pre>int lua_toboolean (lua_State *L, int index);</pre> |
| r242899 | r242900 | |
| 4978 | 4697 | <p> |
| 4979 | 4698 | Converts the Lua value at the given index |
| 4980 | 4699 | to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>. |
| 4981 | The Lua value must be an integer, | |
| 4982 | or a number or string convertible to an integer (see <a href="#3.4.3">§3.4.3</a>); | |
| 4700 | The Lua value must be a number or a string convertible to a number | |
| 4701 | (see <a href="#3.4.2">§3.4.2</a>); | |
| 4983 | 4702 | otherwise, <code>lua_tointegerx</code> returns 0. |
| 4984 | 4703 | |
| 4985 | 4704 | |
| 4986 | 4705 | <p> |
| 4706 | If the number is not an integer, | |
| 4707 | it is truncated in some non-specified way. | |
| 4708 | ||
| 4709 | ||
| 4710 | <p> | |
| 4987 | 4711 | If <code>isnum</code> is not <code>NULL</code>, |
| 4988 | 4712 | its referent is assigned a boolean value that |
| 4989 | 4713 | indicates whether the operation succeeded. |
| r242899 | r242900 | |
| 5015 | 4739 | This string always has a zero ('<code>\0</code>') |
| 5016 | 4740 | after its last character (as in C), |
| 5017 | 4741 | but can contain other zeros in its body. |
| 5018 | ||
| 5019 | ||
| 5020 | <p> | |
| 5021 | 4742 | Because Lua has garbage collection, |
| 5022 | 4743 | there is no guarantee that the pointer returned by <code>lua_tolstring</code> |
| 5023 | will be valid after the corresponding | |
| 4744 | will be valid after the corresponding value is removed from the stack. | |
| 5024 | 4745 | |
| 5025 | 4746 | |
| 5026 | 4747 | |
| r242899 | r242900 | |
| 5045 | 4766 | Converts the Lua value at the given index |
| 5046 | 4767 | to the C type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>). |
| 5047 | 4768 | The Lua value must be a number or a string convertible to a number |
| 5048 | (see <a href="#3.4. | |
| 4769 | (see <a href="#3.4.2">§3.4.2</a>); | |
| 5049 | 4770 | otherwise, <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> returns 0. |
| 5050 | 4771 | |
| 5051 | 4772 | |
| r242899 | r242900 | |
| 5103 | 4824 | |
| 5104 | 4825 | |
| 5105 | 4826 | |
| 4827 | <hr><h3><a name="lua_tounsigned"><code>lua_tounsigned</code></a></h3><p> | |
| 4828 | <span class="apii">[-0, +0, –]</span> | |
| 4829 | <pre>lua_Unsigned lua_tounsigned (lua_State *L, int index);</pre> | |
| 4830 | ||
| 4831 | <p> | |
| 4832 | Equivalent to <a href="#lua_tounsignedx"><code>lua_tounsignedx</code></a> with <code>isnum</code> equal to <code>NULL</code>. | |
| 4833 | ||
| 4834 | ||
| 4835 | ||
| 4836 | ||
| 4837 | ||
| 4838 | <hr><h3><a name="lua_tounsignedx"><code>lua_tounsignedx</code></a></h3><p> | |
| 4839 | <span class="apii">[-0, +0, –]</span> | |
| 4840 | <pre>lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);</pre> | |
| 4841 | ||
| 4842 | <p> | |
| 4843 | Converts the Lua value at the given index | |
| 4844 | to the unsigned integral type <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>. | |
| 4845 | The Lua value must be a number or a string convertible to a number | |
| 4846 | (see <a href="#3.4.2">§3.4.2</a>); | |
| 4847 | otherwise, <code>lua_tounsignedx</code> returns 0. | |
| 4848 | ||
| 4849 | ||
| 4850 | <p> | |
| 4851 | If the number is not an integer, | |
| 4852 | it is truncated in some non-specified way. | |
| 4853 | If the number is outside the range of representable values, | |
| 4854 | it is normalized to the remainder of its division by | |
| 4855 | one more than the maximum representable value. | |
| 4856 | ||
| 4857 | ||
| 4858 | <p> | |
| 4859 | If <code>isnum</code> is not <code>NULL</code>, | |
| 4860 | its referent is assigned a boolean value that | |
| 4861 | indicates whether the operation succeeded. | |
| 4862 | ||
| 4863 | ||
| 4864 | ||
| 4865 | ||
| 4866 | ||
| 5106 | 4867 | <hr><h3><a name="lua_touserdata"><code>lua_touserdata</code></a></h3><p> |
| 5107 | 4868 | <span class="apii">[-0, +0, –]</span> |
| 5108 | 4869 | <pre>void *lua_touserdata (lua_State *L, int index);</pre> |
| r242899 | r242900 | |
| 5155 | 4916 | |
| 5156 | 4917 | |
| 5157 | 4918 | <hr><h3><a name="lua_Unsigned"><code>lua_Unsigned</code></a></h3> |
| 5158 | <pre>typedef | |
| 4919 | <pre>typedef unsigned long lua_Unsigned;</pre> | |
| 5159 | 4920 | |
| 5160 | 4921 | <p> |
| 5161 | The unsigned version of <a href="#lua_Integer"><code>lua_Integer</code></a>. | |
| 4922 | The type used by the Lua API to represent unsigned integral values. | |
| 4923 | It must have at least 32 bits. | |
| 5162 | 4924 | |
| 5163 | 4925 | |
| 4926 | <p> | |
| 4927 | By default it is an <code>unsigned int</code> or an <code>unsigned long</code>, | |
| 4928 | whichever can hold 32-bit values. | |
| 5164 | 4929 | |
| 5165 | 4930 | |
| 5166 | 4931 | |
| 4932 | ||
| 4933 | ||
| 5167 | 4934 | <hr><h3><a name="lua_upvalueindex"><code>lua_upvalueindex</code></a></h3><p> |
| 5168 | 4935 | <span class="apii">[-0, +0, –]</span> |
| 5169 | 4936 | <pre>int lua_upvalueindex (int i);</pre> |
| r242899 | r242900 | |
| 5233 | 5000 | |
| 5234 | 5001 | |
| 5235 | 5002 | <hr><h3><a name="lua_yield"><code>lua_yield</code></a></h3><p> |
| 5236 | <span class="apii">[-?, +?, | |
| 5003 | <span class="apii">[-?, +?, –]</span> | |
| 5237 | 5004 | <pre>int lua_yield (lua_State *L, int nresults);</pre> |
| 5238 | 5005 | |
| 5239 | 5006 | <p> |
| 5240 | 5007 | This function is equivalent to <a href="#lua_yieldk"><code>lua_yieldk</code></a>, |
| 5241 | 5008 | but it has no continuation (see <a href="#4.7">§4.7</a>). |
| 5242 | 5009 | Therefore, when the thread resumes, |
| 5243 | it | |
| 5010 | it returns to the function that called | |
| 5244 | 5011 | the function calling <code>lua_yield</code>. |
| 5245 | 5012 | |
| 5246 | 5013 | |
| r242899 | r242900 | |
| 5248 | 5015 | |
| 5249 | 5016 | |
| 5250 | 5017 | <hr><h3><a name="lua_yieldk"><code>lua_yieldk</code></a></h3><p> |
| 5251 | <span class="apii">[-?, +?, <em>e</em>]</span> | |
| 5252 | <pre>int lua_yieldk (lua_State *L, | |
| 5253 | int nresults, | |
| 5254 | lua_KContext ctx, | |
| 5255 | lua_KFunction k);</pre> | |
| 5018 | <span class="apii">[-?, +?, –]</span> | |
| 5019 | <pre>int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k);</pre> | |
| 5256 | 5020 | |
| 5257 | 5021 | <p> |
| 5258 | Yields a coroutine | |
| 5022 | Yields a coroutine. | |
| 5259 | 5023 | |
| 5260 | 5024 | |
| 5261 | 5025 | <p> |
| 5262 | When a C function calls <a href="#lua_yieldk"><code>lua_yieldk</code></a>, | |
| 5026 | This function should only be called as the | |
| 5027 | return expression of a C function, as follows: | |
| 5028 | ||
| 5029 | <pre> | |
| 5030 | return lua_yieldk (L, n, i, k); | |
| 5031 | </pre><p> | |
| 5032 | When a C function calls <a href="#lua_yieldk"><code>lua_yieldk</code></a> in that way, | |
| 5263 | 5033 | the running coroutine suspends its execution, |
| 5264 | 5034 | and the call to <a href="#lua_resume"><code>lua_resume</code></a> that started this coroutine returns. |
| 5265 | 5035 | The parameter <code>nresults</code> is the number of values from the stack |
| 5266 | that | |
| 5036 | that are passed as results to <a href="#lua_resume"><code>lua_resume</code></a>. | |
| 5267 | 5037 | |
| 5268 | 5038 | |
| 5269 | 5039 | <p> |
| r242899 | r242900 | |
| 5272 | 5042 | the execution of the C function that yielded (see <a href="#4.7">§4.7</a>). |
| 5273 | 5043 | This continuation function receives the same stack |
| 5274 | 5044 | from the previous function, |
| 5275 | with the | |
| 5045 | with the results removed and | |
| 5276 | 5046 | replaced by the arguments passed to <a href="#lua_resume"><code>lua_resume</code></a>. |
| 5277 | 5047 | Moreover, |
| 5278 | the continuation function receives the value <code>ctx</code> | |
| 5279 | that was passed to <a href="#lua_yieldk"><code>lua_yieldk</code></a>. | |
| 5048 | the continuation function may access the value <code>ctx</code> | |
| 5049 | by calling <a href="#lua_getctx"><code>lua_getctx</code></a>. | |
| 5280 | 5050 | |
| 5281 | 5051 | |
| 5282 | <p> | |
| 5283 | Usually, this function does not return; | |
| 5284 | when the coroutine eventually resumes, | |
| 5285 | it continues executing the continuation function. | |
| 5286 | However, there is one special case, | |
| 5287 | which is when this function is called | |
| 5288 | from inside a line hook (see <a href="#4.9">§4.9</a>). | |
| 5289 | In that case, <code>lua_yieldk</code> should be called with no continuation | |
| 5290 | (probably in the form of <a href="#lua_yield"><code>lua_yield</code></a>), | |
| 5291 | and the hook should return immediately after the call. | |
| 5292 | Lua will yield and, | |
| 5293 | when the coroutine resumes again, | |
| 5294 | it will continue the normal execution | |
| 5295 | of the (Lua) function that triggered the hook. | |
| 5296 | 5052 | |
| 5297 | 5053 | |
| 5298 | <p> | |
| 5299 | This function can raise an error if it is called from a thread | |
| 5300 | with a pending C call with no continuation function, | |
| 5301 | or it is called from a thread that is not running inside a resume | |
| 5302 | (e.g., the main thread). | |
| 5303 | 5054 | |
| 5304 | 5055 | |
| 5305 | 5056 | |
| 5306 | ||
| 5307 | ||
| 5308 | ||
| 5309 | ||
| 5310 | 5057 | <h2>4.9 – <a name="4.9">The Debug Interface</a></h2> |
| 5311 | 5058 | |
| 5312 | 5059 | <p> |
| r242899 | r242900 | |
| 5353 | 5100 | <ul> |
| 5354 | 5101 | |
| 5355 | 5102 | <li><b><code>source</code>: </b> |
| 5356 | the | |
| 5103 | the source of the chunk that created the function. | |
| 5357 | 5104 | If <code>source</code> starts with a '<code>@</code>', |
| 5358 | 5105 | it means that the function was defined in a file where |
| 5359 | 5106 | the file name follows the '<code>@</code>'. |
| r242899 | r242900 | |
| 5532 | 5279 | (A <em>valid line</em> is a line with some associated code, |
| 5533 | 5280 | that is, a line where you can put a break point. |
| 5534 | 5281 | Non-valid lines include empty lines and comments.) |
| 5535 | ||
| 5536 | ||
| 5537 | <p> | |
| 5538 | If this option is given together with option '<code>f</code>', | |
| 5539 | its table is pushed after the function. | |
| 5540 | 5282 | </li> |
| 5541 | 5283 | |
| 5542 | 5284 | </ul> |
| r242899 | r242900 | |
| 5551 | 5293 | |
| 5552 | 5294 | <hr><h3><a name="lua_getlocal"><code>lua_getlocal</code></a></h3><p> |
| 5553 | 5295 | <span class="apii">[-0, +(0|1), –]</span> |
| 5554 | <pre>const char *lua_getlocal (lua_State *L, | |
| 5296 | <pre>const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);</pre> | |
| 5555 | 5297 | |
| 5556 | 5298 | <p> |
| 5557 | 5299 | Gets information about a local variable of |
| r242899 | r242900 | |
| 5574 | 5316 | |
| 5575 | 5317 | |
| 5576 | 5318 | <p> |
| 5577 | In the second case, <code>ar</code> | |
| 5319 | In the second case, <code>ar</code> should be <code>NULL</code> and the function | |
| 5578 | 5320 | to be inspected must be at the top of the stack. |
| 5579 | 5321 | In this case, only parameters of Lua functions are visible |
| 5580 | 5322 | (as there is no information about what variables are active) |
| r242899 | r242900 | |
| 5691 | 5433 | |
| 5692 | 5434 | <hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p> |
| 5693 | 5435 | <span class="apii">[-0, +0, –]</span> |
| 5694 | <pre> | |
| 5436 | <pre>int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre> | |
| 5695 | 5437 | |
| 5696 | 5438 | <p> |
| 5697 | 5439 | Sets the debugging hook function. |
| r242899 | r242900 | |
| 5744 | 5486 | |
| 5745 | 5487 | <hr><h3><a name="lua_setlocal"><code>lua_setlocal</code></a></h3><p> |
| 5746 | 5488 | <span class="apii">[-(0|1), +0, –]</span> |
| 5747 | <pre>const char *lua_setlocal (lua_State *L, | |
| 5489 | <pre>const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);</pre> | |
| 5748 | 5490 | |
| 5749 | 5491 | <p> |
| 5750 | 5492 | Sets the value of a local variable of a given activation record. |
| r242899 | r242900 | |
| 5790 | 5532 | <pre>void *lua_upvalueid (lua_State *L, int funcindex, int n);</pre> |
| 5791 | 5533 | |
| 5792 | 5534 | <p> |
| 5793 | Returns a unique identifier for the upvalue numbered <code>n</code> | |
| 5535 | Returns an unique identifier for the upvalue numbered <code>n</code> | |
| 5794 | 5536 | from the closure at index <code>funcindex</code>. |
| 5795 | 5537 | Parameters <code>funcindex</code> and <code>n</code> are as in the <a href="#lua_getupvalue"><code>lua_getupvalue</code></a> |
| 5796 | 5538 | (see <a href="#lua_getupvalue"><code>lua_getupvalue</code></a>) |
| r242899 | r242900 | |
| 5867 | 5609 | |
| 5868 | 5610 | <p> |
| 5869 | 5611 | Functions called <code>luaL_check*</code> |
| 5870 | always r | |
| 5612 | always throw an error if the check is not satisfied. | |
| 5871 | 5613 | |
| 5872 | 5614 | |
| 5873 | 5615 | |
| r242899 | r242900 | |
| 5926 | 5668 | Adds the zero-terminated string pointed to by <code>s</code> |
| 5927 | 5669 | to the buffer <code>B</code> |
| 5928 | 5670 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). |
| 5671 | The string cannot contain embedded zeros. | |
| 5929 | 5672 | |
| 5930 | 5673 | |
| 5931 | 5674 | |
| r242899 | r242900 | |
| 5960 | 5703 | |
| 5961 | 5704 | <p> |
| 5962 | 5705 | Checks whether <code>cond</code> is true. |
| 5963 | If | |
| 5706 | If not, raises an error with a standard message. | |
| 5964 | 5707 | |
| 5965 | 5708 | |
| 5966 | 5709 | |
| r242899 | r242900 | |
| 5971 | 5714 | <pre>int luaL_argerror (lua_State *L, int arg, const char *extramsg);</pre> |
| 5972 | 5715 | |
| 5973 | 5716 | <p> |
| 5974 | Raises an error reporting a problem with argument <code>arg</code> | |
| 5975 | of the C function that called it, | |
| 5976 | using a standard message | |
| 5977 | that includes <code>extramsg</code> as a comment: | |
| 5717 | Raises an error with a standard message | |
| 5718 | that includes <code>extramsg</code> as a comment. | |
| 5978 | 5719 | |
| 5979 | <pre> | |
| 5980 | bad argument #<em>arg</em> to '<em>funcname</em>' (<em>extramsg</em>) | |
| 5981 | </pre><p> | |
| 5982 | This function never returns. | |
| 5983 | 5720 | |
| 5721 | <p> | |
| 5722 | This function never returns, | |
| 5723 | but it is an idiom to use it in C functions | |
| 5724 | as <code>return luaL_argerror(<em>args</em>)</code>. | |
| 5984 | 5725 | |
| 5985 | 5726 | |
| 5986 | 5727 | |
| 5987 | 5728 | |
| 5729 | ||
| 5988 | 5730 | <hr><h3><a name="luaL_Buffer"><code>luaL_Buffer</code></a></h3> |
| 5989 | 5731 | <pre>typedef struct luaL_Buffer luaL_Buffer;</pre> |
| 5990 | 5732 | |
| r242899 | r242900 | |
| 6114 | 5856 | |
| 6115 | 5857 | |
| 6116 | 5858 | |
| 5859 | <hr><h3><a name="luaL_checkint"><code>luaL_checkint</code></a></h3><p> | |
| 5860 | <span class="apii">[-0, +0, <em>v</em>]</span> | |
| 5861 | <pre>int luaL_checkint (lua_State *L, int arg);</pre> | |
| 5862 | ||
| 5863 | <p> | |
| 5864 | Checks whether the function argument <code>arg</code> is a number | |
| 5865 | and returns this number cast to an <code>int</code>. | |
| 5866 | ||
| 5867 | ||
| 5868 | ||
| 5869 | ||
| 5870 | ||
| 6117 | 5871 | <hr><h3><a name="luaL_checkinteger"><code>luaL_checkinteger</code></a></h3><p> |
| 6118 | 5872 | <span class="apii">[-0, +0, <em>v</em>]</span> |
| 6119 | 5873 | <pre>lua_Integer luaL_checkinteger (lua_State *L, int arg);</pre> |
| 6120 | 5874 | |
| 6121 | 5875 | <p> |
| 6122 | Checks whether the function argument <code>arg</code> is an integer | |
| 6123 | (or can be converted to an integer) | |
| 6124 | and returns this integer cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>. | |
| 5876 | Checks whether the function argument <code>arg</code> is a number | |
| 5877 | and returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>. | |
| 6125 | 5878 | |
| 6126 | 5879 | |
| 6127 | 5880 | |
| 6128 | 5881 | |
| 6129 | 5882 | |
| 5883 | <hr><h3><a name="luaL_checklong"><code>luaL_checklong</code></a></h3><p> | |
| 5884 | <span class="apii">[-0, +0, <em>v</em>]</span> | |
| 5885 | <pre>long luaL_checklong (lua_State *L, int arg);</pre> | |
| 5886 | ||
| 5887 | <p> | |
| 5888 | Checks whether the function argument <code>arg</code> is a number | |
| 5889 | and returns this number cast to a <code>long</code>. | |
| 5890 | ||
| 5891 | ||
| 5892 | ||
| 5893 | ||
| 5894 | ||
| 6130 | 5895 | <hr><h3><a name="luaL_checklstring"><code>luaL_checklstring</code></a></h3><p> |
| 6131 | 5896 | <span class="apii">[-0, +0, <em>v</em>]</span> |
| 6132 | 5897 | <pre>const char *luaL_checklstring (lua_State *L, int arg, size_t *l);</pre> |
| r242899 | r242900 | |
| 6245 | 6010 | |
| 6246 | 6011 | |
| 6247 | 6012 | |
| 6013 | <hr><h3><a name="luaL_checkunsigned"><code>luaL_checkunsigned</code></a></h3><p> | |
| 6014 | <span class="apii">[-0, +0, <em>v</em>]</span> | |
| 6015 | <pre>lua_Unsigned luaL_checkunsigned (lua_State *L, int arg);</pre> | |
| 6016 | ||
| 6017 | <p> | |
| 6018 | Checks whether the function argument <code>arg</code> is a number | |
| 6019 | and returns this number cast to a <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>. | |
| 6020 | ||
| 6021 | ||
| 6022 | ||
| 6023 | ||
| 6024 | ||
| 6248 | 6025 | <hr><h3><a name="luaL_checkversion"><code>luaL_checkversion</code></a></h3><p> |
| 6249 | 6026 | <span class="apii">[-0, +0, –]</span> |
| 6250 | 6027 | <pre>void luaL_checkversion (lua_State *L);</pre> |
| r242899 | r242900 | |
| 6352 | 6129 | |
| 6353 | 6130 | <p> |
| 6354 | 6131 | Pushes onto the stack the field <code>e</code> from the metatable |
| 6355 | of the object at index <code>obj</code> | |
| 6132 | of the object at index <code>obj</code>. | |
| 6356 | 6133 | If the object does not have a metatable, |
| 6357 | 6134 | or if the metatable does not have this field, |
| 6358 | pushes nothing | |
| 6135 | returns false and pushes nothing. | |
| 6359 | 6136 | |
| 6360 | 6137 | |
| 6361 | 6138 | |
| r242899 | r242900 | |
| 6363 | 6140 | |
| 6364 | 6141 | <hr><h3><a name="luaL_getmetatable"><code>luaL_getmetatable</code></a></h3><p> |
| 6365 | 6142 | <span class="apii">[-0, +1, –]</span> |
| 6366 | <pre>i | |
| 6143 | <pre>void luaL_getmetatable (lua_State *L, const char *tname);</pre> | |
| 6367 | 6144 | |
| 6368 | 6145 | <p> |
| 6369 | 6146 | Pushes onto the stack the metatable associated with name <code>tname</code> |
| 6370 | 6147 | in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>). |
| 6371 | If there is no metatable associated with <code>tname</code>, | |
| 6372 | returns false and pushes <b>nil</b>. | |
| 6373 | 6148 | |
| 6374 | 6149 | |
| 6375 | 6150 | |
| r242899 | r242900 | |
| 6410 | 6185 | |
| 6411 | 6186 | <hr><h3><a name="luaL_len"><code>luaL_len</code></a></h3><p> |
| 6412 | 6187 | <span class="apii">[-0, +0, <em>e</em>]</span> |
| 6413 | <pre> | |
| 6188 | <pre>int luaL_len (lua_State *L, int index);</pre> | |
| 6414 | 6189 | |
| 6415 | 6190 | <p> |
| 6416 | 6191 | Returns the "length" of the value at the given index |
| 6417 | 6192 | as a number; |
| 6418 | it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.7">§3.4.7</a>). | |
| 6419 | Raises an error if the result of the operation is not an integer. | |
| 6193 | it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">§3.4.6</a>). | |
| 6194 | Raises an error if the result of the operation is not a number. | |
| 6420 | 6195 | (This case only can happen through metamethods.) |
| 6421 | 6196 | |
| 6422 | 6197 | |
| r242899 | r242900 | |
| 6528 | 6303 | |
| 6529 | 6304 | <hr><h3><a name="luaL_newlib"><code>luaL_newlib</code></a></h3><p> |
| 6530 | 6305 | <span class="apii">[-0, +1, <em>e</em>]</span> |
| 6531 | <pre>void luaL_newlib (lua_State *L, const luaL_Reg l | |
| 6306 | <pre>void luaL_newlib (lua_State *L, const luaL_Reg *l);</pre> | |
| 6532 | 6307 | |
| 6533 | 6308 | <p> |
| 6534 | 6309 | Creates a new table and registers there |
| 6535 | 6310 | the functions in list <code>l</code>. |
| 6536 | ||
| 6537 | ||
| 6538 | <p> | |
| 6539 | 6311 | It is implemented as the following macro: |
| 6540 | 6312 | |
| 6541 | 6313 | <pre> |
| 6542 | 6314 | (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) |
| 6543 | </pre><p> | |
| 6544 | The array <code>l</code> must be the actual array, | |
| 6545 | not a pointer to it. | |
| 6315 | </pre> | |
| 6546 | 6316 | |
| 6547 | 6317 | |
| 6548 | 6318 | |
| 6549 | 6319 | |
| 6550 | ||
| 6551 | 6320 | <hr><h3><a name="luaL_newlibtable"><code>luaL_newlibtable</code></a></h3><p> |
| 6552 | 6321 | <span class="apii">[-0, +1, <em>e</em>]</span> |
| 6553 | 6322 | <pre>void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);</pre> |
| r242899 | r242900 | |
| 6578 | 6347 | returns 0. |
| 6579 | 6348 | Otherwise, |
| 6580 | 6349 | creates a new table to be used as a metatable for userdata, |
| 6581 | adds to this new table the pair <code>__name = tname</code>, | |
| 6582 | adds to the registry the pair <code>[tname] = new table</code>, | |
| 6350 | adds it to the registry with key <code>tname</code>, | |
| 6583 | 6351 | and returns 1. |
| 6584 | (The entry <code>__name</code> is used by some error-reporting functions.) | |
| 6585 | 6352 | |
| 6586 | 6353 | |
| 6587 | 6354 | <p> |
| r242899 | r242900 | |
| 6624 | 6391 | |
| 6625 | 6392 | |
| 6626 | 6393 | |
| 6394 | <hr><h3><a name="luaL_optint"><code>luaL_optint</code></a></h3><p> | |
| 6395 | <span class="apii">[-0, +0, <em>v</em>]</span> | |
| 6396 | <pre>int luaL_optint (lua_State *L, int arg, int d);</pre> | |
| 6397 | ||
| 6398 | <p> | |
| 6399 | If the function argument <code>arg</code> is a number, | |
| 6400 | returns this number cast to an <code>int</code>. | |
| 6401 | If this argument is absent or is <b>nil</b>, | |
| 6402 | returns <code>d</code>. | |
| 6403 | Otherwise, raises an error. | |
| 6404 | ||
| 6405 | ||
| 6406 | ||
| 6407 | ||
| 6408 | ||
| 6627 | 6409 | <hr><h3><a name="luaL_optinteger"><code>luaL_optinteger</code></a></h3><p> |
| 6628 | 6410 | <span class="apii">[-0, +0, <em>v</em>]</span> |
| 6629 | 6411 | <pre>lua_Integer luaL_optinteger (lua_State *L, |
| r242899 | r242900 | |
| 6631 | 6413 | lua_Integer d);</pre> |
| 6632 | 6414 | |
| 6633 | 6415 | <p> |
| 6634 | If the function argument <code>arg</code> is an integer | |
| 6635 | (or convertible to an integer), | |
| 6636 | returns this integer. | |
| 6416 | If the function argument <code>arg</code> is a number, | |
| 6417 | returns this number cast to a <a href="#lua_Integer"><code>lua_Integer</code></a>. | |
| 6637 | 6418 | If this argument is absent or is <b>nil</b>, |
| 6638 | 6419 | returns <code>d</code>. |
| 6639 | 6420 | Otherwise, raises an error. |
| r242899 | r242900 | |
| 6642 | 6423 | |
| 6643 | 6424 | |
| 6644 | 6425 | |
| 6426 | <hr><h3><a name="luaL_optlong"><code>luaL_optlong</code></a></h3><p> | |
| 6427 | <span class="apii">[-0, +0, <em>v</em>]</span> | |
| 6428 | <pre>long luaL_optlong (lua_State *L, int arg, long d);</pre> | |
| 6429 | ||
| 6430 | <p> | |
| 6431 | If the function argument <code>arg</code> is a number, | |
| 6432 | returns this number cast to a <code>long</code>. | |
| 6433 | If this argument is absent or is <b>nil</b>, | |
| 6434 | returns <code>d</code>. | |
| 6435 | Otherwise, raises an error. | |
| 6436 | ||
| 6437 | ||
| 6438 | ||
| 6439 | ||
| 6440 | ||
| 6645 | 6441 | <hr><h3><a name="luaL_optlstring"><code>luaL_optlstring</code></a></h3><p> |
| 6646 | 6442 | <span class="apii">[-0, +0, <em>v</em>]</span> |
| 6647 | 6443 | <pre>const char *luaL_optlstring (lua_State *L, |
| r242899 | r242900 | |
| 6697 | 6493 | |
| 6698 | 6494 | |
| 6699 | 6495 | |
| 6496 | <hr><h3><a name="luaL_optunsigned"><code>luaL_optunsigned</code></a></h3><p> | |
| 6497 | <span class="apii">[-0, +0, <em>v</em>]</span> | |
| 6498 | <pre>lua_Unsigned luaL_optunsigned (lua_State *L, | |
| 6499 | int arg, | |
| 6500 | lua_Unsigned u);</pre> | |
| 6501 | ||
| 6502 | <p> | |
| 6503 | If the function argument <code>arg</code> is a number, | |
| 6504 | returns this number cast to a <a href="#lua_Unsigned"><code>lua_Unsigned</code></a>. | |
| 6505 | If this argument is absent or is <b>nil</b>, | |
| 6506 | returns <code>u</code>. | |
| 6507 | Otherwise, raises an error. | |
| 6508 | ||
| 6509 | ||
| 6510 | ||
| 6511 | ||
| 6512 | ||
| 6700 | 6513 | <hr><h3><a name="luaL_prepbuffer"><code>luaL_prepbuffer</code></a></h3><p> |
| 6701 | 6514 | <span class="apii">[-?, +?, <em>e</em>]</span> |
| 6702 | 6515 | <pre>char *luaL_prepbuffer (luaL_Buffer *B);</pre> |
| r242899 | r242900 | |
| 6788 | 6601 | <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a>. |
| 6789 | 6602 | <code>name</code> is the function name and <code>func</code> is a pointer to |
| 6790 | 6603 | the function. |
| 6791 | Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with a sentinel entry | |
| 6604 | Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with an sentinel entry | |
| 6792 | 6605 | in which both <code>name</code> and <code>func</code> are <code>NULL</code>. |
| 6793 | 6606 | |
| 6794 | 6607 | |
| r242899 | r242900 | |
| 6801 | 6614 | lua_CFunction openf, int glb);</pre> |
| 6802 | 6615 | |
| 6803 | 6616 | <p> |
| 6804 | If <code>modname</code> is not already present in <a href="#pdf-package.loaded"><code>package.loaded</code></a>, | |
| 6805 | calls function <code>openf</code> with string <code>modname</code> as an argument | |
| 6617 | Calls function <code>openf</code> with string <code>modname</code> as an argument | |
| 6806 | 6618 | and sets the call result in <code>package.loaded[modname]</code>, |
| 6807 | 6619 | as if that function has been called through <a href="#pdf-require"><code>require</code></a>. |
| 6808 | 6620 | |
| 6809 | 6621 | |
| 6810 | 6622 | <p> |
| 6811 | 6623 | If <code>glb</code> is true, |
| 6812 | also stores the | |
| 6624 | also stores the result into global <code>modname</code>. | |
| 6813 | 6625 | |
| 6814 | 6626 | |
| 6815 | 6627 | <p> |
| 6816 | Leaves a copy of th | |
| 6628 | Leaves a copy of that result on the stack. | |
| 6817 | 6629 | |
| 6818 | 6630 | |
| 6819 | 6631 | |
| r242899 | r242900 | |
| 6853 | 6665 | |
| 6854 | 6666 | |
| 6855 | 6667 | |
| 6856 | <hr><h3><a name="luaL_Stream"><code>luaL_Stream</code></a></h3> | |
| 6857 | <pre>typedef struct luaL_Stream { | |
| 6858 | FILE *f; | |
| 6859 | lua_CFunction closef; | |
| 6860 | } luaL_Stream;</pre> | |
| 6861 | ||
| 6862 | <p> | |
| 6863 | The standard representation for file handles, | |
| 6864 | which is used by the standard I/O library. | |
| 6865 | ||
| 6866 | ||
| 6867 | <p> | |
| 6868 | A file handle is implemented as a full userdata, | |
| 6869 | with a metatable called <code>LUA_FILEHANDLE</code> | |
| 6870 | (where <code>LUA_FILEHANDLE</code> is a macro with the actual metatable's name). | |
| 6871 | The metatable is created by the I/O library | |
| 6872 | (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>). | |
| 6873 | ||
| 6874 | ||
| 6875 | <p> | |
| 6876 | This userdata must start with the structure <code>luaL_Stream</code>; | |
| 6877 | it can contain other data after this initial structure. | |
| 6878 | Field <code>f</code> points to the corresponding C stream | |
| 6879 | (or it can be <code>NULL</code> to indicate an incompletely created handle). | |
| 6880 | Field <code>closef</code> points to a Lua function | |
| 6881 | that will be called to close the stream | |
| 6882 | when the handle is closed or collected; | |
| 6883 | this function receives the file handle as its sole argument and | |
| 6884 | must return either <b>true</b> (in case of success) | |
| 6885 | or <b>nil</b> plus an error message (in case of error). | |
| 6886 | Once Lua calls this field, | |
| 6887 | the field value is changed to <code>NULL</code> | |
| 6888 | to signal that the handle is closed. | |
| 6889 | ||
| 6890 | ||
| 6891 | ||
| 6892 | ||
| 6893 | ||
| 6894 | 6668 | <hr><h3><a name="luaL_testudata"><code>luaL_testudata</code></a></h3><p> |
| 6895 | 6669 | <span class="apii">[-0, +0, <em>e</em>]</span> |
| 6896 | 6670 | <pre>void *luaL_testudata (lua_State *L, int arg, const char *tname);</pre> |
| r242899 | r242900 | |
| 6898 | 6672 | <p> |
| 6899 | 6673 | This function works like <a href="#luaL_checkudata"><code>luaL_checkudata</code></a>, |
| 6900 | 6674 | except that, when the test fails, |
| 6901 | it returns <code>NULL</code> instead of r | |
| 6675 | it returns <code>NULL</code> instead of throwing an error. | |
| 6902 | 6676 | |
| 6903 | 6677 | |
| 6904 | 6678 | |
| r242899 | r242900 | |
| 7028 | 6802 | |
| 7029 | 6803 | <li>string manipulation (<a href="#6.4">§6.4</a>);</li> |
| 7030 | 6804 | |
| 7031 | <li>ba | |
| 6805 | <li>table manipulation (<a href="#6.5">§6.5</a>);</li> | |
| 7032 | 6806 | |
| 7033 | <li> | |
| 6807 | <li>mathematical functions (<a href="#6.6">§6.6</a>) (sin, log, etc.);</li> | |
| 7034 | 6808 | |
| 7035 | <li> | |
| 6809 | <li>bitwise operations (<a href="#6.7">§6.7</a>);</li> | |
| 7036 | 6810 | |
| 7037 | 6811 | <li>input and output (<a href="#6.8">§6.8</a>);</li> |
| 7038 | 6812 | |
| r242899 | r242900 | |
| 7057 | 6831 | <a name="pdf-luaopen_package"><code>luaopen_package</code></a> (for the package library), |
| 7058 | 6832 | <a name="pdf-luaopen_coroutine"><code>luaopen_coroutine</code></a> (for the coroutine library), |
| 7059 | 6833 | <a name="pdf-luaopen_string"><code>luaopen_string</code></a> (for the string library), |
| 7060 | <a name="pdf-luaopen_utf8"><code>luaopen_utf8</code></a> (for the UTF8 library), | |
| 7061 | 6834 | <a name="pdf-luaopen_table"><code>luaopen_table</code></a> (for the table library), |
| 7062 | 6835 | <a name="pdf-luaopen_math"><code>luaopen_math</code></a> (for the mathematical library), |
| 6836 | <a name="pdf-luaopen_bit32"><code>luaopen_bit32</code></a> (for the bit library), | |
| 7063 | 6837 | <a name="pdf-luaopen_io"><code>luaopen_io</code></a> (for the I/O library), |
| 7064 | <a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the | |
| 6838 | <a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the Operating System library), | |
| 7065 | 6839 | and <a name="pdf-luaopen_debug"><code>luaopen_debug</code></a> (for the debug library). |
| 7066 | 6840 | These functions are declared in <a name="pdf-lualib.h"><code>lualib.h</code></a>. |
| 7067 | 6841 | |
| r242899 | r242900 | |
| 7078 | 6852 | |
| 7079 | 6853 | <p> |
| 7080 | 6854 | <hr><h3><a name="pdf-assert"><code>assert (v [, message])</code></a></h3> |
| 7081 | ||
| 7082 | ||
| 7083 | <p> | |
| 7084 | Calls <a href="#pdf-error"><code>error</code></a> if | |
| 6855 | Issues an error when | |
| 7085 | 6856 | the value of its argument <code>v</code> is false (i.e., <b>nil</b> or <b>false</b>); |
| 7086 | 6857 | otherwise, returns all its arguments. |
| 7087 | In case of error, | |
| 7088 | <code>message</code> is the error object; | |
| 7089 | when absent, it defaults to "<code>assertion failed!</code>" | |
| 6858 | <code>message</code> is an error message; | |
| 6859 | when absent, it defaults to "assertion failed!" | |
| 7090 | 6860 | |
| 7091 | 6861 | |
| 7092 | 6862 | |
| r242899 | r242900 | |
| 7117 | 6887 | </li> |
| 7118 | 6888 | |
| 7119 | 6889 | <li><b>"<code>count</code>": </b> |
| 7120 | returns the total memory in use by Lua in Kbytes. | |
| 7121 | The value has a fractional part, | |
| 7122 | so that it multiplied by 1024 | |
| 7123 | gives the exact number of bytes in use by Lua | |
| 7124 | (except for overflows). | |
| 6890 | returns the total memory in use by Lua (in Kbytes) and | |
| 6891 | a second value with the total memory in bytes modulo 1024. | |
| 6892 | The first value has a fractional part, | |
| 6893 | so the following equality is always true: | |
| 6894 | ||
| 6895 | <pre> | |
| 6896 | k, b = collectgarbage("count") | |
| 6897 | assert(k*1024 == math.floor(k)*1024 + b) | |
| 6898 | </pre><p> | |
| 6899 | (The second result is useful when Lua is compiled | |
| 6900 | with a non floating-point type for numbers.) | |
| 7125 | 6901 | </li> |
| 7126 | 6902 | |
| 7127 | 6903 | <li><b>"<code>step</code>": </b> |
| 7128 | 6904 | performs a garbage-collection step. |
| 7129 | The step "size" is controlled by <code>arg</code>. | |
| 7130 | With a zero value, | |
| 7131 | the collector will perform one basic (indivisible) step. | |
| 7132 | For non-zero values, | |
| 7133 | the collector will perform as if that amount of memory | |
| 7134 | (in KBytes) had been allocated by Lua. | |
| 6905 | The step "size" is controlled by <code>arg</code> | |
| 6906 | (larger values mean more steps) in a non-specified way. | |
| 6907 | If you want to control the step size | |
| 6908 | you must experimentally tune the value of <code>arg</code>. | |
| 7135 | 6909 | Returns <b>true</b> if the step finished a collection cycle. |
| 7136 | 6910 | </li> |
| 7137 | 6911 | |
| r242899 | r242900 | |
| 7152 | 6926 | (i.e., not stopped). |
| 7153 | 6927 | </li> |
| 7154 | 6928 | |
| 6929 | <li><b>"<code>generational</code>": </b> | |
| 6930 | changes the collector to generational mode. | |
| 6931 | This is an experimental feature (see <a href="#2.5">§2.5</a>). | |
| 6932 | </li> | |
| 6933 | ||
| 6934 | <li><b>"<code>incremental</code>": </b> | |
| 6935 | changes the collector to incremental mode. | |
| 6936 | This is the default mode. | |
| 6937 | </li> | |
| 6938 | ||
| 7155 | 6939 | </ul> |
| 7156 | 6940 | |
| 7157 | 6941 | |
| r242899 | r242900 | |
| 7171 | 6955 | <p> |
| 7172 | 6956 | <hr><h3><a name="pdf-error"><code>error (message [, level])</code></a></h3> |
| 7173 | 6957 | Terminates the last protected function called |
| 7174 | and returns <code>message</code> as the error | |
| 6958 | and returns <code>message</code> as the error message. | |
| 7175 | 6959 | Function <code>error</code> never returns. |
| 7176 | 6960 | |
| 7177 | 6961 | |
| r242899 | r242900 | |
| 7195 | 6979 | holds the global environment (see <a href="#2.2">§2.2</a>). |
| 7196 | 6980 | Lua itself does not use this variable; |
| 7197 | 6981 | changing its value does not affect any environment, |
| 7198 | nor vice | |
| 6982 | nor vice-versa. | |
| 7199 | 6983 | |
| 7200 | 6984 | |
| 7201 | 6985 | |
| r242899 | r242900 | |
| 7219 | 7003 | |
| 7220 | 7004 | |
| 7221 | 7005 | <p> |
| 7222 | Returns three values (an iterator function, the table <code>t</code>, and 0) | |
| 7006 | If <code>t</code> has a metamethod <code>__ipairs</code>, | |
| 7007 | calls it with <code>t</code> as argument and returns the first three | |
| 7008 | results from the call. | |
| 7009 | ||
| 7010 | ||
| 7011 | <p> | |
| 7012 | Otherwise, | |
| 7013 | returns three values: an iterator function, the table <code>t</code>, and 0, | |
| 7223 | 7014 | so that the construction |
| 7224 | 7015 | |
| 7225 | 7016 | <pre> |
| 7226 | 7017 | for i,v in ipairs(t) do <em>body</em> end |
| 7227 | 7018 | </pre><p> |
| 7228 | will iterate over the key–value pairs | |
| 7229 | (<code>1,t[1]</code>), (<code>2,t[2]</code>), ..., | |
| 7230 | up to the first nil value. | |
| 7019 | will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), ..., | |
| 7020 | up to the first integer key absent from the table. | |
| 7231 | 7021 | |
| 7232 | 7022 | |
| 7233 | 7023 | |
| 7234 | 7024 | |
| 7235 | 7025 | <p> |
| 7236 | <hr><h3><a name="pdf-load"><code>load ( | |
| 7026 | <hr><h3><a name="pdf-load"><code>load (ld [, source [, mode [, env]]])</code></a></h3> | |
| 7237 | 7027 | |
| 7238 | 7028 | |
| 7239 | 7029 | <p> |
| r242899 | r242900 | |
| 7241 | 7031 | |
| 7242 | 7032 | |
| 7243 | 7033 | <p> |
| 7244 | If <code>chunk</code> is a string, the chunk is this string. | |
| 7245 | If <code>chunk</code> is a function, | |
| 7034 | If <code>ld</code> is a string, the chunk is this string. | |
| 7035 | If <code>ld</code> is a function, | |
| 7246 | 7036 | <code>load</code> calls it repeatedly to get the chunk pieces. |
| 7247 | Each call to <code> | |
| 7037 | Each call to <code>ld</code> must return a string that concatenates | |
| 7248 | 7038 | with previous results. |
| 7249 | 7039 | A return of an empty string, <b>nil</b>, or no value signals the end of the chunk. |
| 7250 | 7040 | |
| r242899 | r242900 | |
| 7260 | 7050 | the first upvalue is set to the value of <code>env</code>, |
| 7261 | 7051 | if that parameter is given, |
| 7262 | 7052 | or to the value of the global environment. |
| 7263 | Other upvalues are initialized with <b>nil</b>. | |
| 7264 | 7053 | (When you load a main chunk, |
| 7265 | 7054 | the resulting function will always have exactly one upvalue, |
| 7266 | 7055 | the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>). |
| 7267 | However, | |
| 7268 | when you load a binary chunk created from a function (see <a href="#pdf-string.dump"><code>string.dump</code></a>), | |
| 7269 | the resulting function can have an arbitrary number of upvalues.) | |
| 7270 | All upvalues are fresh, that is, | |
| 7271 | they are not shared with any other function. | |
| 7056 | When you load a binary chunk created from a function (see <a href="#pdf-string.dump"><code>string.dump</code></a>), | |
| 7057 | the resulting function can have arbitrary upvalues.) | |
| 7272 | 7058 | |
| 7273 | 7059 | |
| 7274 | 7060 | <p> |
| 7275 | <code> | |
| 7061 | <code>source</code> is used as the source of the chunk for error messages | |
| 7276 | 7062 | and debug information (see <a href="#4.9">§4.9</a>). |
| 7277 | 7063 | When absent, |
| 7278 | it defaults to <code> | |
| 7064 | it defaults to <code>ld</code>, if <code>ld</code> is a string, | |
| 7279 | 7065 | or to "<code>=(load)</code>" otherwise. |
| 7280 | 7066 | |
| 7281 | 7067 | |
| r242899 | r242900 | |
| 7288 | 7074 | The default is "<code>bt</code>". |
| 7289 | 7075 | |
| 7290 | 7076 | |
| 7291 | <p> | |
| 7292 | Lua does not check the consistency of binary chunks. | |
| 7293 | Maliciously crafted binary chunks can crash | |
| 7294 | the interpreter. | |
| 7295 | 7077 | |
| 7296 | 7078 | |
| 7297 | ||
| 7298 | ||
| 7299 | 7079 | <p> |
| 7300 | 7080 | <hr><h3><a name="pdf-loadfile"><code>loadfile ([filename [, mode [, env]]])</code></a></h3> |
| 7301 | 7081 | |
| r242899 | r242900 | |
| 7432 | 7212 | Returns the length of the object <code>v</code>, |
| 7433 | 7213 | which must be a table or a string, |
| 7434 | 7214 | without invoking any metamethod. |
| 7435 | Returns an integer. | |
| 7215 | Returns an integer number. | |
| 7436 | 7216 | |
| 7437 | 7217 | |
| 7438 | 7218 | |
| r242899 | r242900 | |
| 7493 | 7273 | When called with no <code>base</code>, |
| 7494 | 7274 | <code>tonumber</code> tries to convert its argument to a number. |
| 7495 | 7275 | If the argument is already a number or |
| 7496 | a string convertible to a number, | |
| 7276 | a string convertible to a number (see <a href="#3.4.2">§3.4.2</a>), | |
| 7497 | 7277 | then <code>tonumber</code> returns this number; |
| 7498 | 7278 | otherwise, it returns <b>nil</b>. |
| 7499 | 7279 | |
| 7500 | 7280 | |
| 7501 | 7281 | <p> |
| 7502 | The conversion of strings can result in integers or floats, | |
| 7503 | according to the lexical conventions of Lua (see <a href="#3.1">§3.1</a>). | |
| 7504 | (The string may have leading and trailing spaces and a sign.) | |
| 7505 | ||
| 7506 | ||
| 7507 | <p> | |
| 7508 | 7282 | When called with <code>base</code>, |
| 7509 | then <code>e</code> | |
| 7283 | then <code>e</code> should be a string to be interpreted as | |
| 7510 | 7284 | an integer numeral in that base. |
| 7511 | 7285 | The base may be any integer between 2 and 36, inclusive. |
| 7512 | 7286 | In bases above 10, the letter '<code>A</code>' (in either upper or lower case) |
| r242899 | r242900 | |
| 7521 | 7295 | <p> |
| 7522 | 7296 | <hr><h3><a name="pdf-tostring"><code>tostring (v)</code></a></h3> |
| 7523 | 7297 | Receives a value of any type and |
| 7524 | converts it to a string in a human-readable format. | |
| 7525 | Floats always produce strings with some | |
| 7526 | floating-point indication (either a decimal dot or an exponent). | |
| 7298 | converts it to a string in a reasonable format. | |
| 7527 | 7299 | (For complete control of how numbers are converted, |
| 7528 | 7300 | use <a href="#pdf-string.format"><code>string.format</code></a>.) |
| 7529 | 7301 | |
| r242899 | r242900 | |
| 7557 | 7329 | <hr><h3><a name="pdf-_VERSION"><code>_VERSION</code></a></h3> |
| 7558 | 7330 | A global variable (not a function) that |
| 7559 | 7331 | holds a string containing the current interpreter version. |
| 7560 | The current | |
| 7332 | The current contents of this variable is "<code>Lua 5.2</code>". | |
| 7561 | 7333 | |
| 7562 | 7334 | |
| 7563 | 7335 | |
| r242899 | r242900 | |
| 7598 | 7370 | |
| 7599 | 7371 | |
| 7600 | 7372 | <p> |
| 7601 | <hr><h3><a name="pdf-coroutine.isyieldable"><code>coroutine.isyieldable ()</code></a></h3> | |
| 7602 | ||
| 7603 | ||
| 7604 | <p> | |
| 7605 | Returns true when the running coroutine can yield. | |
| 7606 | ||
| 7607 | ||
| 7608 | <p> | |
| 7609 | A running coroutine is yieldable if it is not the main thread and | |
| 7610 | it is not inside a non-yieldable C function. | |
| 7611 | ||
| 7612 | ||
| 7613 | ||
| 7614 | ||
| 7615 | <p> | |
| 7616 | 7373 | <hr><h3><a name="pdf-coroutine.resume"><code>coroutine.resume (co [, val1, ···])</code></a></h3> |
| 7617 | 7374 | |
| 7618 | 7375 | |
| r242899 | r242900 | |
| 7631 | 7388 | <p> |
| 7632 | 7389 | If the coroutine runs without any errors, |
| 7633 | 7390 | <code>resume</code> returns <b>true</b> plus any values passed to <code>yield</code> |
| 7634 | (when the coroutine yields) or any values returned by the body function | |
| 7635 | (when the coroutine terminates). | |
| 7391 | (if the coroutine yields) or any values returned by the body function | |
| 7392 | (if the coroutine terminates). | |
| 7636 | 7393 | If there is any error, |
| 7637 | 7394 | <code>resume</code> returns <b>false</b> plus the error message. |
| 7638 | 7395 | |
| r242899 | r242900 | |
| 7734 | 7491 | <p> |
| 7735 | 7492 | First <code>require</code> queries <code>package.preload[modname]</code>. |
| 7736 | 7493 | If it has a value, |
| 7737 | this value (which | |
| 7494 | this value (which should be a function) is the loader. | |
| 7738 | 7495 | Otherwise <code>require</code> searches for a Lua loader using the |
| 7739 | 7496 | path stored in <a href="#pdf-package.path"><code>package.path</code></a>. |
| 7740 | 7497 | If that also fails, it searches for a C loader using the |
| r242899 | r242900 | |
| 7790 | 7547 | is replaced by the executable's directory. |
| 7791 | 7548 | Default is '<code>!</code>'.</li> |
| 7792 | 7549 | |
| 7793 | <li>The fifth line is a mark to ignore all text | |
| 7550 | <li>The fifth line is a mark to ignore all text before it | |
| 7794 | 7551 | when building the <code>luaopen_</code> function name. |
| 7795 | 7552 | Default is '<code>-</code>'.</li> |
| 7796 | 7553 | |
| r242899 | r242900 | |
| 7809 | 7566 | <p> |
| 7810 | 7567 | Lua initializes the C path <a href="#pdf-package.cpath"><code>package.cpath</code></a> in the same way |
| 7811 | 7568 | it initializes the Lua path <a href="#pdf-package.path"><code>package.path</code></a>, |
| 7812 | using the environment variable <a name="pdf-LUA_CPATH_5_ | |
| 7569 | using the environment variable <a name="pdf-LUA_CPATH_5_2"><code>LUA_CPATH_5_2</code></a> | |
| 7813 | 7570 | or the environment variable <a name="pdf-LUA_CPATH"><code>LUA_CPATH</code></a> |
| 7814 | 7571 | or a default path defined in <code>luaconf.h</code>. |
| 7815 | 7572 | |
| r242899 | r242900 | |
| 7887 | 7644 | |
| 7888 | 7645 | <p> |
| 7889 | 7646 | At start-up, Lua initializes this variable with |
| 7890 | the value of the environment variable <a name="pdf-LUA_PATH_5_ | |
| 7647 | the value of the environment variable <a name="pdf-LUA_PATH_5_2"><code>LUA_PATH_5_2</code></a> or | |
| 7891 | 7648 | the environment variable <a name="pdf-LUA_PATH"><code>LUA_PATH</code></a> or |
| 7892 | 7649 | with a default path defined in <code>luaconf.h</code>, |
| 7893 | 7650 | if those environment variables are not defined. |
| r242899 | r242900 | |
| 7972 | 7729 | concatenated with a copy of the module name where each dot |
| 7973 | 7730 | is replaced by an underscore. |
| 7974 | 7731 | Moreover, if the module name has a hyphen, |
| 7975 | its suffix after (and including) the first hyphen is removed. | |
| 7976 | For instance, if the module name is <code>a.b.c-v2.1</code>, | |
| 7977 | the function name will be <code>luaopen_a_b_c</code>. | |
| 7732 | its prefix up to (and including) the first hyphen is removed. | |
| 7733 | For instance, if the module name is <code>a.v1-b.c</code>, | |
| 7734 | the function name will be <code>luaopen_b_c</code>. | |
| 7978 | 7735 | |
| 7979 | 7736 | |
| 7980 | 7737 | <p> |
| r242899 | r242900 | |
| 8102 | 7859 | |
| 8103 | 7860 | |
| 8104 | 7861 | <p> |
| 8105 | <hr><h3><a name="pdf-string.dump"><code>string.dump (function | |
| 7862 | <hr><h3><a name="pdf-string.dump"><code>string.dump (function)</code></a></h3> | |
| 8106 | 7863 | |
| 8107 | 7864 | |
| 8108 | 7865 | <p> |
| 8109 | Returns a string containing a binary representation | |
| 8110 | (a <em>binary chunk</em>) | |
| 8111 | of the given function, | |
| 7866 | Returns a string containing a binary representation of the given function, | |
| 8112 | 7867 | so that a later <a href="#pdf-load"><code>load</code></a> on this string returns |
| 8113 | 7868 | a copy of the function (but with new upvalues). |
| 8114 | If <code>strip</code> is a true value, | |
| 8115 | the binary representation is created without debug information | |
| 8116 | about the function | |
| 8117 | (local variable names, lines, etc.). | |
| 8118 | 7869 | |
| 8119 | 7870 | |
| 8120 | <p> | |
| 8121 | Functions with upvalues have only their number of upvalues saved. | |
| 8122 | When (re)loaded, | |
| 8123 | those upvalues receive fresh instances containing <b>nil</b>. | |
| 8124 | (You can use the debug library to serialize | |
| 8125 | and reload the upvalues of a function | |
| 8126 | in a way adequate to your needs.) | |
| 8127 | 7871 | |
| 8128 | 7872 | |
| 8129 | ||
| 8130 | ||
| 8131 | 7873 | <p> |
| 8132 | 7874 | <hr><h3><a name="pdf-string.find"><code>string.find (s, pattern [, init [, plain]])</code></a></h3> |
| 8133 | 7875 | |
| 8134 | 7876 | |
| 8135 | 7877 | <p> |
| 8136 | 7878 | Looks for the first match of |
| 8137 | <code>pattern</code> | |
| 7879 | <code>pattern</code> in the string <code>s</code>. | |
| 8138 | 7880 | If it finds a match, then <code>find</code> returns the indices of <code>s</code> |
| 8139 | 7881 | where this occurrence starts and ends; |
| 8140 | 7882 | otherwise, it returns <b>nil</b>. |
| r242899 | r242900 | |
| 8164 | 7906 | <p> |
| 8165 | 7907 | Returns a formatted version of its variable number of arguments |
| 8166 | 7908 | following the description given in its first argument (which must be a string). |
| 8167 | The format string follows the same rules as the | |
| 7909 | The format string follows the same rules as the ANSI C function <code>sprintf</code>. | |
| 8168 | 7910 | The only differences are that the options/modifiers |
| 8169 | 7911 | <code>*</code>, <code>h</code>, <code>L</code>, <code>l</code>, <code>n</code>, |
| 8170 | 7912 | and <code>p</code> are not supported |
| r242899 | r242900 | |
| 8191 | 7933 | <code>G</code>, and <code>g</code> all expect a number as argument. |
| 8192 | 7934 | Options <code>c</code>, <code>d</code>, |
| 8193 | 7935 | <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> |
| 8194 | expect an integer. | |
| 7936 | also expect a number, | |
| 7937 | but the range of that number may be limited by | |
| 7938 | the underlying C implementation. | |
| 7939 | For options <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code>, | |
| 7940 | the number cannot be negative. | |
| 8195 | 7941 | Option <code>q</code> expects a string; |
| 8196 | 7942 | option <code>s</code> expects a string without embedded zeros. |
| 8197 | 7943 | If the argument to option <code>s</code> is not a string, |
| r242899 | r242900 | |
| 8204 | 7950 | <hr><h3><a name="pdf-string.gmatch"><code>string.gmatch (s, pattern)</code></a></h3> |
| 8205 | 7951 | Returns an iterator function that, |
| 8206 | 7952 | each time it is called, |
| 8207 | returns the next captures from <code>pattern</code> (see <a href="#6.4.1">§6.4.1</a>) | |
| 8208 | over the string <code>s</code>. | |
| 7953 | returns the next captures from <code>pattern</code> over the string <code>s</code>. | |
| 8209 | 7954 | If <code>pattern</code> specifies no captures, |
| 8210 | 7955 | then the whole match is produced in each call. |
| 8211 | 7956 | |
| r242899 | r242900 | |
| 8243 | 7988 | <hr><h3><a name="pdf-string.gsub"><code>string.gsub (s, pattern, repl [, n])</code></a></h3> |
| 8244 | 7989 | Returns a copy of <code>s</code> |
| 8245 | 7990 | in which all (or the first <code>n</code>, if given) |
| 8246 | occurrences of the <code>pattern</code> | |
| 7991 | occurrences of the <code>pattern</code> have been | |
| 8247 | 7992 | replaced by a replacement string specified by <code>repl</code>, |
| 8248 | 7993 | which can be a string, a table, or a function. |
| 8249 | 7994 | <code>gsub</code> also returns, as its second value, |
| r242899 | r242900 | |
| 8308 | 8053 | end) |
| 8309 | 8054 | --> x="4+5 = 9" |
| 8310 | 8055 | |
| 8311 | local t = {name="lua", version="5. | |
| 8056 | local t = {name="lua", version="5.2"} | |
| 8312 | 8057 | x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t) |
| 8313 | --> x="lua-5. | |
| 8058 | --> x="lua-5.2.tar.gz" | |
| 8314 | 8059 | </pre> |
| 8315 | 8060 | |
| 8316 | 8061 | |
| r242899 | r242900 | |
| 8338 | 8083 | <p> |
| 8339 | 8084 | <hr><h3><a name="pdf-string.match"><code>string.match (s, pattern [, init])</code></a></h3> |
| 8340 | 8085 | Looks for the first <em>match</em> of |
| 8341 | <code>pattern</code> | |
| 8086 | <code>pattern</code> in the string <code>s</code>. | |
| 8342 | 8087 | If it finds one, then <code>match</code> returns |
| 8343 | 8088 | the captures from the pattern; |
| 8344 | 8089 | otherwise it returns <b>nil</b>. |
| r242899 | r242900 | |
| 8352 | 8097 | |
| 8353 | 8098 | |
| 8354 | 8099 | <p> |
| 8355 | <hr><h3><a name="pdf-string.pack"><code>string.pack (fmt, v1, v2, ···)</code></a></h3> | |
| 8356 | ||
| 8357 | ||
| 8358 | <p> | |
| 8359 | Returns a binary string containing the values <code>v1</code>, <code>v2</code>, etc. | |
| 8360 | packed (that is, serialized in binary form) | |
| 8361 | according to the format string <code>fmt</code> (see <a href="#6.4.2">§6.4.2</a>). | |
| 8362 | ||
| 8363 | ||
| 8364 | ||
| 8365 | ||
| 8366 | <p> | |
| 8367 | <hr><h3><a name="pdf-string.packsize"><code>string.packsize (fmt)</code></a></h3> | |
| 8368 | ||
| 8369 | ||
| 8370 | <p> | |
| 8371 | Returns the size of a string resulting from <a href="#pdf-string.pack"><code>string.pack</code></a> | |
| 8372 | with the given format. | |
| 8373 | The format string cannot have the variable-length options | |
| 8374 | '<code>s</code>' or '<code>z</code>' (see <a href="#6.4.2">§6.4.2</a>). | |
| 8375 | ||
| 8376 | ||
| 8377 | ||
| 8378 | ||
| 8379 | <p> | |
| 8380 | 8100 | <hr><h3><a name="pdf-string.rep"><code>string.rep (s, n [, sep])</code></a></h3> |
| 8381 | 8101 | Returns a string that is the concatenation of <code>n</code> copies of |
| 8382 | 8102 | the string <code>s</code> separated by the string <code>sep</code>. |
| 8383 | 8103 | The default value for <code>sep</code> is the empty string |
| 8384 | 8104 | (that is, no separator). |
| 8385 | Returns the empty string if <code>n</code> is not positive. | |
| 8386 | 8105 | |
| 8387 | 8106 | |
| 8388 | 8107 | |
| r242899 | r242900 | |
| 8422 | 8141 | |
| 8423 | 8142 | |
| 8424 | 8143 | <p> |
| 8425 | <hr><h3><a name="pdf-string.unpack"><code>string.unpack (fmt, s [, pos])</code></a></h3> | |
| 8426 | ||
| 8427 | ||
| 8428 | <p> | |
| 8429 | Returns the values packed in string <code>s</code> (see <a href="#pdf-string.pack"><code>string.pack</code></a>) | |
| 8430 | according to the format string <code>fmt</code> (see <a href="#6.4.2">§6.4.2</a>). | |
| 8431 | An optional <code>pos</code> marks where | |
| 8432 | to start reading in <code>s</code> (default is 1). | |
| 8433 | After the read values, | |
| 8434 | this function also returns the index of the first unread byte in <code>s</code>. | |
| 8435 | ||
| 8436 | ||
| 8437 | ||
| 8438 | ||
| 8439 | <p> | |
| 8440 | 8144 | <hr><h3><a name="pdf-string.upper"><code>string.upper (s)</code></a></h3> |
| 8441 | 8145 | Receives a string and returns a copy of this string with all |
| 8442 | 8146 | lowercase letters changed to uppercase. |
| r242899 | r242900 | |
| 8445 | 8149 | |
| 8446 | 8150 | |
| 8447 | 8151 | |
| 8448 | ||
| 8449 | ||
| 8450 | 8152 | <h3>6.4.1 – <a name="6.4.1">Patterns</a></h3> |
| 8451 | 8153 | |
| 8452 | <p> | |
| 8453 | Patterns in Lua are described by regular strings, | |
| 8454 | which are interpreted as patterns by the pattern-matching functions | |
| 8455 | <a href="#pdf-string.find"><code>string.find</code></a>, | |
| 8456 | <a href="#pdf-string.gmatch"><code>string.gmatch</code></a>, | |
| 8457 | <a href="#pdf-string.gsub"><code>string.gsub</code></a>, | |
| 8458 | and <a href="#pdf-string.match"><code>string.match</code></a>. | |
| 8459 | This section describes the syntax and the meaning | |
| 8460 | (that is, what they match) of these strings. | |
| 8461 | 8154 | |
| 8462 | ||
| 8463 | ||
| 8464 | 8155 | <h4>Character Class:</h4><p> |
| 8465 | 8156 | A <em>character class</em> is used to represent a set of characters. |
| 8466 | 8157 | The following combinations are allowed in describing a character class: |
| r242899 | r242900 | |
| 8498 | 8189 | <li><b><code>%<em>x</em></code>: </b> (where <em>x</em> is any non-alphanumeric character) |
| 8499 | 8190 | represents the character <em>x</em>. |
| 8500 | 8191 | This is the standard way to escape the magic characters. |
| 8501 | Any non-alphanumeric character | |
| 8502 | (including all punctuations, even the non-magical) | |
| 8192 | Any punctuation character (even the non magic) | |
| 8503 | 8193 | can be preceded by a '<code>%</code>' |
| 8504 | 8194 | when used to represent itself in a pattern. |
| 8505 | 8195 | </li> |
| r242899 | r242900 | |
| 8509 | 8199 | characters in <em>set</em>. |
| 8510 | 8200 | A range of characters can be specified by |
| 8511 | 8201 | separating the end characters of the range, |
| 8512 | in ascending order, with a '<code>-</code>' | |
| 8202 | in ascending order, with a '<code>-</code>', | |
| 8513 | 8203 | All classes <code>%</code><em>x</em> described above can also be used as |
| 8514 | 8204 | components in <em>set</em>. |
| 8515 | 8205 | All other characters in <em>set</em> represent themselves. |
| r242899 | r242900 | |
| 8558 | 8248 | |
| 8559 | 8249 | <li> |
| 8560 | 8250 | a single character class followed by '<code>*</code>', |
| 8561 | which matches | |
| 8251 | which matches 0 or more repetitions of characters in the class. | |
| 8562 | 8252 | These repetition items will always match the longest possible sequence; |
| 8563 | 8253 | </li> |
| 8564 | 8254 | |
| 8565 | 8255 | <li> |
| 8566 | 8256 | a single character class followed by '<code>+</code>', |
| 8567 | which matches | |
| 8257 | which matches 1 or more repetitions of characters in the class. | |
| 8568 | 8258 | These repetition items will always match the longest possible sequence; |
| 8569 | 8259 | </li> |
| 8570 | 8260 | |
| 8571 | 8261 | <li> |
| 8572 | 8262 | a single character class followed by '<code>-</code>', |
| 8573 | which also matches | |
| 8263 | which also matches 0 or more repetitions of characters in the class. | |
| 8574 | 8264 | Unlike '<code>*</code>', |
| 8575 | 8265 | these repetition items will always match the shortest possible sequence; |
| 8576 | 8266 | </li> |
| 8577 | 8267 | |
| 8578 | 8268 | <li> |
| 8579 | 8269 | a single character class followed by '<code>?</code>', |
| 8580 | which matches zero or one occurrence of a character in the class. | |
| 8581 | It always matches one occurrence if possible; | |
| 8270 | which matches 0 or 1 occurrence of a character in the class; | |
| 8582 | 8271 | </li> |
| 8583 | 8272 | |
| 8584 | 8273 | <li> |
| r242899 | r242900 | |
| 8651 | 8340 | |
| 8652 | 8341 | |
| 8653 | 8342 | |
| 8654 | <h3>6.4.2 – <a name="6.4.2">Format Strings for Pack and Unpack</a></h3> | |
| 8655 | 8343 | |
| 8656 | <p> | |
| 8657 | The first argument to <a href="#pdf-string.pack"><code>string.pack</code></a>, | |
| 8658 | <a href="#pdf-string.packsize"><code>string.packsize</code></a>, and <a href="#pdf-string.unpack"><code>string.unpack</code></a> | |
| 8659 | is a format string, | |
| 8660 | which describes the layout of the structure being created or read. | |
| 8661 | 8344 | |
| 8662 | 8345 | |
| 8663 | <p> | |
| 8664 | A format string is a sequence of conversion options. | |
| 8665 | The conversion options are as follows: | |
| 8666 | 8346 | |
| 8667 | <ul> | |
| 8668 | <li><b><code><</code>: </b>sets little endian</li> | |
| 8669 | <li><b><code>></code>: </b>sets big endian</li> | |
| 8670 | <li><b><code>=</code>: </b>sets native endian</li> | |
| 8671 | <li><b><code>![<em>n</em>]</code>: </b>sets maximum alignment to <code>n</code> | |
| 8672 | (default is native alignment)</li> | |
| 8673 | <li><b><code>b</code>: </b>a signed byte (<code>char</code>)</li> | |
| 8674 | <li><b><code>B</code>: </b>an unsigned byte (<code>char</code>)</li> | |
| 8675 | <li><b><code>h</code>: </b>a signed <code>short</code> (native size)</li> | |
| 8676 | <li><b><code>H</code>: </b>an unsigned <code>short</code> (native size)</li> | |
| 8677 | <li><b><code>l</code>: </b>a signed <code>long</code> (native size)</li> | |
| 8678 | <li><b><code>L</code>: </b>an unsigned <code>long</code> (native size)</li> | |
| 8679 | <li><b><code>j</code>: </b>a <code>lua_Integer</code></li> | |
| 8680 | <li><b><code>J</code>: </b>a <code>lua_Unsigned</code></li> | |
| 8681 | <li><b><code>T</code>: </b>a <code>size_t</code> (native size)</li> | |
| 8682 | <li><b><code>i[<em>n</em>]</code>: </b>a signed <code>int</code> with <code>n</code> bytes | |
| 8683 | (default is native size)</li> | |
| 8684 | <li><b><code>I[<em>n</em>]</code>: </b>an unsigned <code>int</code> with <code>n</code> bytes | |
| 8685 | (default is native size)</li> | |
| 8686 | <li><b><code>f</code>: </b>a <code>float</code> (native size)</li> | |
| 8687 | <li><b><code>d</code>: </b>a <code>double</code> (native size)</li> | |
| 8688 | <li><b><code>n</code>: </b>a <code>lua_Number</code></li> | |
| 8689 | <li><b><code>c<em>n</em></code>: </b>a fixed-sized string with <code>n</code> bytes</li> | |
| 8690 | <li><b><code>z</code>: </b>a zero-terminated string</li> | |
| 8691 | <li><b><code>s[<em>n</em>]</code>: </b>a string preceded by its length | |
| 8692 | coded as an unsigned integer with <code>n</code> bytes | |
| 8693 | (default is a <code>size_t</code>)</li> | |
| 8694 | <li><b><code>x</code>: </b>one byte of padding</li> | |
| 8695 | <li><b><code>X<em>op</em></code>: </b>an empty item that aligns | |
| 8696 | according to option <code>op</code> | |
| 8697 | (which is otherwise ignored)</li> | |
| 8698 | <li><b>'<code> </code>': </b>(empty space) ignored</li> | |
| 8699 | </ul><p> | |
| 8700 | (A "<code>[<em>n</em>]</code>" means an optional integral numeral.) | |
| 8701 | Except for padding, spaces, and configurations | |
| 8702 | (options "<code>xX <=>!</code>"), | |
| 8703 | each option corresponds to an argument (in <a href="#pdf-string.pack"><code>string.pack</code></a>) | |
| 8704 | or a result (in <a href="#pdf-string.unpack"><code>string.unpack</code></a>). | |
| 8347 | <h2>6.5 – <a name="6.5">Table Manipulation</a></h2> | |
| 8705 | 8348 | |
| 8706 | ||
| 8707 | 8349 | <p> |
| 8708 | For options "<code>!<em>n</em></code>", "<code>s<em>n</em></code>", "<code>i<em>n</em></code>", and "<code>I<em>n</em></code>", | |
| 8709 | <code>n</code> can be any integer between 1 and 16. | |
| 8710 | All integral options check overflows; | |
| 8711 | <a href="#pdf-string.pack"><code>string.pack</code></a> checks whether the given value fits in the given size; | |
| 8712 | <a href="#pdf-string.unpack"><code>string.unpack</code></a> checks whether the read value fits in a Lua integer. | |
| 8713 | ||
| 8714 | ||
| 8715 | <p> | |
| 8716 | Any format string starts as if prefixed by "<code>!1=</code>", | |
| 8717 | that is, | |
| 8718 | with maximum alignment of 1 (no alignment) | |
| 8719 | and native endianness. | |
| 8720 | ||
| 8721 | ||
| 8722 | <p> | |
| 8723 | Alignment works as follows: | |
| 8724 | For each option, | |
| 8725 | the format gets extra padding until the data starts | |
| 8726 | at an offset that is a multiple of the minimum between the | |
| 8727 | option size and the maximum alignment; | |
| 8728 | this minimum must be a power of 2. | |
| 8729 | Options "<code>c</code>" and "<code>z</code>" are not aligned; | |
| 8730 | option "<code>s</code>" follows the alignment of its starting integer. | |
| 8731 | ||
| 8732 | ||
| 8733 | <p> | |
| 8734 | All padding is filled with zeros by <a href="#pdf-string.pack"><code>string.pack</code></a> | |
| 8735 | (and ignored by <a href="#pdf-string.unpack"><code>string.unpack</code></a>). | |
| 8736 | ||
| 8737 | ||
| 8738 | ||
| 8739 | ||
| 8740 | ||
| 8741 | ||
| 8742 | ||
| 8743 | <h2>6.5 – <a name="6.5">UTF-8 Support</a></h2> | |
| 8744 | ||
| 8745 | <p> | |
| 8746 | This library provides basic support for UTF-8 encoding. | |
| 8747 | It provides all its functions inside the table <a name="pdf-utf8"><code>utf8</code></a>. | |
| 8748 | This library does not provide any support for Unicode other | |
| 8749 | than the handling of the encoding. | |
| 8750 | Any operation that needs the meaning of a character, | |
| 8751 | such as character classification, is outside its scope. | |
| 8752 | ||
| 8753 | ||
| 8754 | <p> | |
| 8755 | Unless stated otherwise, | |
| 8756 | all functions that expect a byte position as a parameter | |
| 8757 | assume that the given position is either the start of a byte sequence | |
| 8758 | or one plus the length of the subject string. | |
| 8759 | As in the string library, | |
| 8760 | negative indices count from the end of the string. | |
| 8761 | ||
| 8762 | ||
| 8763 | <p> | |
| 8764 | <hr><h3><a name="pdf-utf8.char"><code>utf8.char (···)</code></a></h3> | |
| 8765 | Receives zero or more integers, | |
| 8766 | converts each one to its corresponding UTF-8 byte sequence | |
| 8767 | and returns a string with the concatenation of all these sequences. | |
| 8768 | ||
| 8769 | ||
| 8770 | ||
| 8771 | ||
| 8772 | <p> | |
| 8773 | <hr><h3><a name="pdf-utf8.charpattern"><code>utf8.charpattern</code></a></h3> | |
| 8774 | The pattern (a string, not a function) "<code>[\0-\x7F\xC2-\xF4][\x80-\xBF]*</code>" | |
| 8775 | (see <a href="#6.4.1">§6.4.1</a>), | |
| 8776 | which matches exactly one UTF-8 byte sequence, | |
| 8777 | assuming that the subject is a valid UTF-8 string. | |
| 8778 | ||
| 8779 | ||
| 8780 | ||
| 8781 | ||
| 8782 | <p> | |
| 8783 | <hr><h3><a name="pdf-utf8.codes"><code>utf8.codes (s)</code></a></h3> | |
| 8784 | ||
| 8785 | ||
| 8786 | <p> | |
| 8787 | Returns values so that the construction | |
| 8788 | ||
| 8789 | <pre> | |
| 8790 | for p, c in utf8.codes(s) do <em>body</em> end | |
| 8791 | </pre><p> | |
| 8792 | will iterate over all characters in string <code>s</code>, | |
| 8793 | with <code>p</code> being the position (in bytes) and <code>c</code> the code point | |
| 8794 | of each character. | |
| 8795 | It raises an error if it meets any invalid byte sequence. | |
| 8796 | ||
| 8797 | ||
| 8798 | ||
| 8799 | ||
| 8800 | <p> | |
| 8801 | <hr><h3><a name="pdf-utf8.codepoint"><code>utf8.codepoint (s [, i [, j]])</code></a></h3> | |
| 8802 | Returns the codepoints (as integers) from all characters in <code>s</code> | |
| 8803 | that start between byte position <code>i</code> and <code>j</code> (both included). | |
| 8804 | The default for <code>i</code> is 1 and for <code>j</code> is <code>i</code>. | |
| 8805 | It raises an error if it meets any invalid byte sequence. | |
| 8806 | ||
| 8807 | ||
| 8808 | ||
| 8809 | ||
| 8810 | <p> | |
| 8811 | <hr><h3><a name="pdf-utf8.len"><code>utf8.len (s [, i [, j]])</code></a></h3> | |
| 8812 | Returns the number of UTF-8 characters in string <code>s</code> | |
| 8813 | that start between positions <code>i</code> and <code>j</code> (both inclusive). | |
| 8814 | The default for <code>i</code> is 1 and for <code>j</code> is -1. | |
| 8815 | If it finds any invalid byte sequence, | |
| 8816 | returns a false value plus the position of the first invalid byte. | |
| 8817 | ||
| 8818 | ||
| 8819 | ||
| 8820 | ||
| 8821 | <p> | |
| 8822 | <hr><h3><a name="pdf-utf8.offset"><code>utf8.offset (s, n [, i])</code></a></h3> | |
| 8823 | Returns the position (in bytes) where the encoding of the | |
| 8824 | <code>n</code>-th character of <code>s</code> | |
| 8825 | (counting from position <code>i</code>) starts. | |
| 8826 | A negative <code>n</code> gets characters before position <code>i</code>. | |
| 8827 | The default for <code>i</code> is 1 when <code>n</code> is non-negative | |
| 8828 | and <code>#s + 1</code> otherwise, | |
| 8829 | so that <code>utf8.offset(s, -n)</code> gets the offset of the | |
| 8830 | <code>n</code>-th character from the end of the string. | |
| 8831 | If the specified character is neither in the subject | |
| 8832 | nor right after its end, | |
| 8833 | the function returns <b>nil</b>. | |
| 8834 | ||
| 8835 | ||
| 8836 | <p> | |
| 8837 | As a special case, | |
| 8838 | when <code>n</code> is 0 the function returns the start of the encoding | |
| 8839 | of the character that contains the <code>i</code>-th byte of <code>s</code>. | |
| 8840 | ||
| 8841 | ||
| 8842 | <p> | |
| 8843 | This function assumes that <code>s</code> is a valid UTF-8 string. | |
| 8844 | ||
| 8845 | ||
| 8846 | ||
| 8847 | ||
| 8848 | ||
| 8849 | ||
| 8850 | ||
| 8851 | <h2>6.6 – <a name="6.6">Table Manipulation</a></h2> | |
| 8852 | ||
| 8853 | <p> | |
| 8854 | 8350 | This library provides generic functions for table manipulation. |
| 8855 | 8351 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. |
| 8856 | 8352 | |
| 8857 | 8353 | |
| 8858 | 8354 | <p> |
| 8859 | 8355 | Remember that, whenever an operation needs the length of a table, |
| 8860 | the table must be a proper sequence | |
| 8861 | or have a <code>__len</code> metamethod (see <a href="#3.4.7">§3.4.7</a>). | |
| 8356 | the table should be a proper sequence | |
| 8357 | or have a <code>__len</code> metamethod (see <a href="#3.4.6">§3.4.6</a>). | |
| 8862 | 8358 | All functions ignore non-numeric keys |
| 8863 | in t | |
| 8359 | in tables given as arguments. | |
| 8864 | 8360 | |
| 8865 | 8361 | |
| 8866 | 8362 | <p> |
| 8363 | For performance reasons, | |
| 8364 | all table accesses (get/set) performed by these functions are raw. | |
| 8365 | ||
| 8366 | ||
| 8367 | <p> | |
| 8867 | 8368 | <hr><h3><a name="pdf-table.concat"><code>table.concat (list [, sep [, i [, j]]])</code></a></h3> |
| 8868 | 8369 | |
| 8869 | 8370 | |
| r242899 | r242900 | |
| 8894 | 8395 | |
| 8895 | 8396 | |
| 8896 | 8397 | <p> |
| 8897 | <hr><h3><a name="pdf-table.move"><code>table.move (a1, f, e, t [,a2])</code></a></h3> | |
| 8898 | ||
| 8899 | ||
| 8900 | <p> | |
| 8901 | Moves elements from table <code>a1</code> to table <code>a2</code>. | |
| 8902 | This function performs the equivalent to the following | |
| 8903 | multiple assignment: | |
| 8904 | <code>a2[t],··· = a1[f],···,a1[e]</code>. | |
| 8905 | The default for <code>a2</code> is <code>a1</code>. | |
| 8906 | The destination range can overlap with the source range. | |
| 8907 | Index <code>f</code> must be positive. | |
| 8908 | ||
| 8909 | ||
| 8910 | ||
| 8911 | ||
| 8912 | <p> | |
| 8913 | 8398 | <hr><h3><a name="pdf-table.pack"><code>table.pack (···)</code></a></h3> |
| 8914 | 8399 | |
| 8915 | 8400 | |
| r242899 | r242900 | |
| 8939 | 8424 | |
| 8940 | 8425 | <p> |
| 8941 | 8426 | The default value for <code>pos</code> is <code>#list</code>, |
| 8942 | so that a call <code>table.remove(l)</code> removes the last element | |
| 8943 | of list <code>l</code>. | |
| 8427 | so that a call <code>table.remove(t)</code> removes the last element | |
| 8428 | of list <code>t</code>. | |
| 8944 | 8429 | |
| 8945 | 8430 | |
| 8946 | 8431 | |
| r242899 | r242900 | |
| 8974 | 8459 | |
| 8975 | 8460 | |
| 8976 | 8461 | <p> |
| 8977 | Returns the elements from the given | |
| 8462 | Returns the elements from the given table. | |
| 8978 | 8463 | This function is equivalent to |
| 8979 | 8464 | |
| 8980 | 8465 | <pre> |
| r242899 | r242900 | |
| 8988 | 8473 | |
| 8989 | 8474 | |
| 8990 | 8475 | |
| 8991 | <h2>6. | |
| 8476 | <h2>6.6 – <a name="6.6">Mathematical Functions</a></h2> | |
| 8992 | 8477 | |
| 8993 | 8478 | <p> |
| 8994 | This library provides basic mathematical functions. | |
| 8995 | It provides all its functions and constants inside the table <a name="pdf-math"><code>math</code></a>. | |
| 8996 | Functions with the annotation "<code>integer/float</code>" give | |
| 8997 | integer results for integer arguments | |
| 8998 | and float results for float (or mixed) arguments. | |
| 8999 | Rounding functions | |
| 9000 | (<a href="#pdf-math.ceil"><code>math.ceil</code></a>, <a href="#pdf-math.floor"><code>math.floor</code></a>, and <a href="#pdf-math.modf"><code>math.modf</code></a>) | |
| 9001 | return an integer when the result fits in the range of an integer, | |
| 9002 | or a float otherwise. | |
| 8479 | This library is an interface to the standard C math library. | |
| 8480 | It provides all its functions inside the table <a name="pdf-math"><code>math</code></a>. | |
| 9003 | 8481 | |
| 9004 | 8482 | |
| 9005 | 8483 | <p> |
| r242899 | r242900 | |
| 9007 | 8485 | |
| 9008 | 8486 | |
| 9009 | 8487 | <p> |
| 9010 | Returns the absolute value of <code>x</code>. | |
| 8488 | Returns the absolute value of <code>x</code>. | |
| 9011 | 8489 | |
| 9012 | 8490 | |
| 9013 | 8491 | |
| r242899 | r242900 | |
| 9033 | 8511 | |
| 9034 | 8512 | |
| 9035 | 8513 | <p> |
| 9036 | <hr><h3><a name="pdf-math.atan"><code>math.atan ( | |
| 8514 | <hr><h3><a name="pdf-math.atan"><code>math.atan (x)</code></a></h3> | |
| 9037 | 8515 | |
| 9038 | 8516 | |
| 9039 | 8517 | <p> |
| 8518 | Returns the arc tangent of <code>x</code> (in radians). | |
| 9040 | 8519 | |
| 8520 | ||
| 8521 | ||
| 8522 | ||
| 8523 | <p> | |
| 8524 | <hr><h3><a name="pdf-math.atan2"><code>math.atan2 (y, x)</code></a></h3> | |
| 8525 | ||
| 8526 | ||
| 8527 | <p> | |
| 9041 | 8528 | Returns the arc tangent of <code>y/x</code> (in radians), |
| 9042 | 8529 | but uses the signs of both parameters to find the |
| 9043 | 8530 | quadrant of the result. |
| 9044 | 8531 | (It also handles correctly the case of <code>x</code> being zero.) |
| 9045 | 8532 | |
| 9046 | 8533 | |
| 9047 | <p> | |
| 9048 | The default value for <code>x</code> is 1, | |
| 9049 | so that the call <code>math.atan(y)</code> | |
| 9050 | returns the arc tangent of <code>y</code>. | |
| 9051 | 8534 | |
| 9052 | 8535 | |
| 9053 | ||
| 9054 | ||
| 9055 | 8536 | <p> |
| 9056 | 8537 | <hr><h3><a name="pdf-math.ceil"><code>math.ceil (x)</code></a></h3> |
| 9057 | 8538 | |
| 9058 | 8539 | |
| 9059 | 8540 | <p> |
| 9060 | Returns the smallest integ | |
| 8541 | Returns the smallest integer larger than or equal to <code>x</code>. | |
| 9061 | 8542 | |
| 9062 | 8543 | |
| 9063 | 8544 | |
| r242899 | r242900 | |
| 9073 | 8554 | |
| 9074 | 8555 | |
| 9075 | 8556 | <p> |
| 8557 | <hr><h3><a name="pdf-math.cosh"><code>math.cosh (x)</code></a></h3> | |
| 8558 | ||
| 8559 | ||
| 8560 | <p> | |
| 8561 | Returns the hyperbolic cosine of <code>x</code>. | |
| 8562 | ||
| 8563 | ||
| 8564 | ||
| 8565 | ||
| 8566 | <p> | |
| 9076 | 8567 | <hr><h3><a name="pdf-math.deg"><code>math.deg (x)</code></a></h3> |
| 9077 | 8568 | |
| 9078 | 8569 | |
| 9079 | 8570 | <p> |
| 9080 | ||
| 8571 | Returns the angle <code>x</code> (given in radians) in degrees. | |
| 9081 | 8572 | |
| 9082 | 8573 | |
| 9083 | 8574 | |
| r242899 | r242900 | |
| 9087 | 8578 | |
| 9088 | 8579 | |
| 9089 | 8580 | <p> |
| 9090 | Returns the value <em>e<sup>x</sup></em> | |
| 9091 | (where <code>e</code> is the base of natural logarithms). | |
| 8581 | Returns the value <em>e<sup>x</sup></em>. | |
| 9092 | 8582 | |
| 9093 | 8583 | |
| 9094 | 8584 | |
| r242899 | r242900 | |
| 9098 | 8588 | |
| 9099 | 8589 | |
| 9100 | 8590 | <p> |
| 9101 | Returns the largest integ | |
| 8591 | Returns the largest integer smaller than or equal to <code>x</code>. | |
| 9102 | 8592 | |
| 9103 | 8593 | |
| 9104 | 8594 | |
| r242899 | r242900 | |
| 9109 | 8599 | |
| 9110 | 8600 | <p> |
| 9111 | 8601 | Returns the remainder of the division of <code>x</code> by <code>y</code> |
| 9112 | that rounds the quotient towards zero. | |
| 8602 | that rounds the quotient towards zero. | |
| 9113 | 8603 | |
| 9114 | 8604 | |
| 9115 | 8605 | |
| 9116 | 8606 | |
| 9117 | 8607 | <p> |
| 9118 | <hr><h3><a name="pdf-math. | |
| 8608 | <hr><h3><a name="pdf-math.frexp"><code>math.frexp (x)</code></a></h3> | |
| 9119 | 8609 | |
| 9120 | 8610 | |
| 9121 | 8611 | <p> |
| 9122 | The float value <code>HUGE_VAL</code>, | |
| 9123 | a value larger than any other numerical value. | |
| 8612 | Returns <code>m</code> and <code>e</code> such that <em>x = m2<sup>e</sup></em>, | |
| 8613 | <code>e</code> is an integer and the absolute value of <code>m</code> is | |
| 8614 | in the range <em>[0.5, 1)</em> | |
| 8615 | (or zero when <code>x</code> is zero). | |
| 9124 | 8616 | |
| 9125 | 8617 | |
| 9126 | 8618 | |
| 9127 | 8619 | |
| 9128 | 8620 | <p> |
| 9129 | <hr><h3><a name="pdf-math. | |
| 8621 | <hr><h3><a name="pdf-math.huge"><code>math.huge</code></a></h3> | |
| 9130 | 8622 | |
| 9131 | 8623 | |
| 9132 | 8624 | <p> |
| 9133 | Returns the logarithm of <code>x</code> in the given base. | |
| 9134 | The default for <code>base</code> is <em>e</em> | |
| 9135 | (so that the function returns the natural logarithm of <code>x</code>). | |
| 8625 | The value <code>HUGE_VAL</code>, | |
| 8626 | a value larger than or equal to any other numerical value. | |
| 9136 | 8627 | |
| 9137 | 8628 | |
| 9138 | 8629 | |
| 9139 | 8630 | |
| 9140 | 8631 | <p> |
| 9141 | <hr><h3><a name="pdf-math. | |
| 8632 | <hr><h3><a name="pdf-math.ldexp"><code>math.ldexp (m, e)</code></a></h3> | |
| 9142 | 8633 | |
| 9143 | 8634 | |
| 9144 | 8635 | <p> |
| 9145 | Returns the argument with the maximum value, | |
| 9146 | according to the Lua operator <code><</code>. (integer/float) | |
| 8636 | Returns <em>m2<sup>e</sup></em> (<code>e</code> should be an integer). | |
| 9147 | 8637 | |
| 9148 | 8638 | |
| 9149 | 8639 | |
| 9150 | 8640 | |
| 9151 | 8641 | <p> |
| 9152 | <hr><h3><a name="pdf-math.maxinteger"><code>math.maxinteger</code></a></h3> | |
| 9153 | An integer with the maximum value for an integer. | |
| 8642 | <hr><h3><a name="pdf-math.log"><code>math.log (x [, base])</code></a></h3> | |
| 9154 | 8643 | |
| 9155 | 8644 | |
| 8645 | <p> | |
| 8646 | Returns the logarithm of <code>x</code> in the given base. | |
| 8647 | The default for <code>base</code> is <em>e</em> | |
| 8648 | (so that the function returns the natural logarithm of <code>x</code>). | |
| 9156 | 8649 | |
| 9157 | 8650 | |
| 8651 | ||
| 8652 | ||
| 9158 | 8653 | <p> |
| 9159 | <hr><h3><a name="pdf-math.m | |
| 8654 | <hr><h3><a name="pdf-math.max"><code>math.max (x, ···)</code></a></h3> | |
| 9160 | 8655 | |
| 9161 | 8656 | |
| 9162 | 8657 | <p> |
| 9163 | Returns the argument with the minimum value, | |
| 9164 | according to the Lua operator <code><</code>. (integer/float) | |
| 8658 | Returns the maximum value among its arguments. | |
| 9165 | 8659 | |
| 9166 | 8660 | |
| 9167 | 8661 | |
| 9168 | 8662 | |
| 9169 | 8663 | <p> |
| 9170 | <hr><h3><a name="pdf-math.mininteger"><code>math.mininteger</code></a></h3> | |
| 9171 | An integer with the minimum value for an integer. | |
| 8664 | <hr><h3><a name="pdf-math.min"><code>math.min (x, ···)</code></a></h3> | |
| 9172 | 8665 | |
| 9173 | 8666 | |
| 8667 | <p> | |
| 8668 | Returns the minimum value among its arguments. | |
| 9174 | 8669 | |
| 9175 | 8670 | |
| 8671 | ||
| 8672 | ||
| 9176 | 8673 | <p> |
| 9177 | 8674 | <hr><h3><a name="pdf-math.modf"><code>math.modf (x)</code></a></h3> |
| 9178 | 8675 | |
| 9179 | 8676 | |
| 9180 | 8677 | <p> |
| 9181 | Returns the integral part of <code>x</code> and the fractional part of <code>x</code>. | |
| 9182 | Its second result is always a float. | |
| 8678 | Returns two numbers, | |
| 8679 | the integral part of <code>x</code> and the fractional part of <code>x</code>. | |
| 9183 | 8680 | |
| 9184 | 8681 | |
| 9185 | 8682 | |
| r242899 | r242900 | |
| 9195 | 8692 | |
| 9196 | 8693 | |
| 9197 | 8694 | <p> |
| 8695 | <hr><h3><a name="pdf-math.pow"><code>math.pow (x, y)</code></a></h3> | |
| 8696 | ||
| 8697 | ||
| 8698 | <p> | |
| 8699 | Returns <em>x<sup>y</sup></em>. | |
| 8700 | (You can also use the expression <code>x^y</code> to compute this value.) | |
| 8701 | ||
| 8702 | ||
| 8703 | ||
| 8704 | ||
| 8705 | <p> | |
| 9198 | 8706 | <hr><h3><a name="pdf-math.rad"><code>math.rad (x)</code></a></h3> |
| 9199 | 8707 | |
| 9200 | 8708 | |
| 9201 | 8709 | <p> |
| 9202 | ||
| 8710 | Returns the angle <code>x</code> (given in degrees) in radians. | |
| 9203 | 8711 | |
| 9204 | 8712 | |
| 9205 | 8713 | |
| r242899 | r242900 | |
| 9209 | 8717 | |
| 9210 | 8718 | |
| 9211 | 8719 | <p> |
| 9212 | When called without arguments, | |
| 9213 | returns a pseudo-random float with uniform distribution | |
| 9214 | in the range <em>[0,1)</em>. | |
| 9215 | When called with two integers <code>m</code> and <code>n</code>, | |
| 9216 | <code>math.random</code> returns a pseudo-random integer | |
| 9217 | with uniform distribution in the range <em>[m, n]</em>. | |
| 9218 | (The value <em>m-n</em> cannot be negative and must fit in a Lua integer.) | |
| 9219 | The call <code>math.random(n)</code> is equivalent to <code>math.random(1,n)</code>. | |
| 8720 | This function is an interface to the simple | |
| 8721 | pseudo-random generator function <code>rand</code> provided by Standard C. | |
| 8722 | (No guarantees can be given for its statistical properties.) | |
| 9220 | 8723 | |
| 9221 | 8724 | |
| 9222 | 8725 | <p> |
| 9223 | This function is an interface to the underling | |
| 9224 | pseudo-random generator function provided by C. | |
| 9225 | No guarantees can be given for its statistical properties. | |
| 8726 | When called without arguments, | |
| 8727 | returns a uniform pseudo-random real number | |
| 8728 | in the range <em>[0,1)</em>. | |
| 8729 | When called with an integer number <code>m</code>, | |
| 8730 | <code>math.random</code> returns | |
| 8731 | a uniform pseudo-random integer in the range <em>[1, m]</em>. | |
| 8732 | When called with two integer numbers <code>m</code> and <code>n</code>, | |
| 8733 | <code>math.random</code> returns a uniform pseudo-random | |
| 8734 | integer in the range <em>[m, n]</em>. | |
| 9226 | 8735 | |
| 9227 | 8736 | |
| 9228 | 8737 | |
| r242899 | r242900 | |
| 9250 | 8759 | |
| 9251 | 8760 | |
| 9252 | 8761 | <p> |
| 8762 | <hr><h3><a name="pdf-math.sinh"><code>math.sinh (x)</code></a></h3> | |
| 8763 | ||
| 8764 | ||
| 8765 | <p> | |
| 8766 | Returns the hyperbolic sine of <code>x</code>. | |
| 8767 | ||
| 8768 | ||
| 8769 | ||
| 8770 | ||
| 8771 | <p> | |
| 9253 | 8772 | <hr><h3><a name="pdf-math.sqrt"><code>math.sqrt (x)</code></a></h3> |
| 9254 | 8773 | |
| 9255 | 8774 | |
| r242899 | r242900 | |
| 9271 | 8790 | |
| 9272 | 8791 | |
| 9273 | 8792 | <p> |
| 9274 | <hr><h3><a name="pdf-math.t | |
| 8793 | <hr><h3><a name="pdf-math.tanh"><code>math.tanh (x)</code></a></h3> | |
| 9275 | 8794 | |
| 9276 | 8795 | |
| 9277 | 8796 | <p> |
| 9278 | If the value <code>x</code> is convertible to an integer, | |
| 9279 | returns that integer. | |
| 9280 | Otherwise, returns <b>nil</b>. | |
| 8797 | Returns the hyperbolic tangent of <code>x</code>. | |
| 9281 | 8798 | |
| 9282 | 8799 | |
| 9283 | 8800 | |
| 9284 | 8801 | |
| 8802 | ||
| 8803 | ||
| 8804 | ||
| 8805 | <h2>6.7 – <a name="6.7">Bitwise Operations</a></h2> | |
| 8806 | ||
| 9285 | 8807 | <p> |
| 9286 | <hr><h3><a name="pdf-math.type"><code>math.type (x)</code></a></h3> | |
| 8808 | This library provides bitwise operations. | |
| 8809 | It provides all its functions inside the table <a name="pdf-bit32"><code>bit32</code></a>. | |
| 9287 | 8810 | |
| 9288 | 8811 | |
| 9289 | 8812 | <p> |
| 9290 | Returns "<code>integer</code>" if <code>x</code> is an integer, | |
| 9291 | "<code>float</code>" if it is a float, | |
| 9292 | or <b>nil</b> if <code>x</code> is not a number. | |
| 8813 | Unless otherwise stated, | |
| 8814 | all functions accept numeric arguments in the range | |
| 8815 | <em>(-2<sup>51</sup>,+2<sup>51</sup>)</em>; | |
| 8816 | each argument is normalized to | |
| 8817 | the remainder of its division by <em>2<sup>32</sup></em> | |
| 8818 | and truncated to an integer (in some unspecified way), | |
| 8819 | so that its final value falls in the range <em>[0,2<sup>32</sup> - 1]</em>. | |
| 8820 | Similarly, all results are in the range <em>[0,2<sup>32</sup> - 1]</em>. | |
| 8821 | Note that <code>bit32.bnot(0)</code> is <code>0xFFFFFFFF</code>, | |
| 8822 | which is different from <code>-1</code>. | |
| 9293 | 8823 | |
| 9294 | 8824 | |
| 8825 | <p> | |
| 8826 | <hr><h3><a name="pdf-bit32.arshift"><code>bit32.arshift (x, disp)</code></a></h3> | |
| 9295 | 8827 | |
| 9296 | 8828 | |
| 9297 | 8829 | <p> |
| 9298 | <hr><h3><a name="pdf-math.ult"><code>math.ult (m, n)</code></a></h3> | |
| 8830 | Returns the number <code>x</code> shifted <code>disp</code> bits to the right. | |
| 8831 | The number <code>disp</code> may be any representable integer. | |
| 8832 | Negative displacements shift to the left. | |
| 9299 | 8833 | |
| 9300 | 8834 | |
| 9301 | 8835 | <p> |
| 9302 | Returns a boolean, | |
| 9303 | true if integer <code>m</code> is below integer <code>n</code> when | |
| 9304 | they are compared as unsigned integers. | |
| 8836 | This shift operation is what is called arithmetic shift. | |
| 8837 | Vacant bits on the left are filled | |
| 8838 | with copies of the higher bit of <code>x</code>; | |
| 8839 | vacant bits on the right are filled with zeros. | |
| 8840 | In particular, | |
| 8841 | displacements with absolute values higher than 31 | |
| 8842 | result in zero or <code>0xFFFFFFFF</code> (all original bits are shifted out). | |
| 9305 | 8843 | |
| 9306 | 8844 | |
| 9307 | 8845 | |
| 9308 | 8846 | |
| 8847 | <p> | |
| 8848 | <hr><h3><a name="pdf-bit32.band"><code>bit32.band (···)</code></a></h3> | |
| 9309 | 8849 | |
| 9310 | 8850 | |
| 8851 | <p> | |
| 8852 | Returns the bitwise <em>and</em> of its operands. | |
| 9311 | 8853 | |
| 8854 | ||
| 8855 | ||
| 8856 | ||
| 8857 | <p> | |
| 8858 | <hr><h3><a name="pdf-bit32.bnot"><code>bit32.bnot (x)</code></a></h3> | |
| 8859 | ||
| 8860 | ||
| 8861 | <p> | |
| 8862 | Returns the bitwise negation of <code>x</code>. | |
| 8863 | For any integer <code>x</code>, | |
| 8864 | the following identity holds: | |
| 8865 | ||
| 8866 | <pre> | |
| 8867 | assert(bit32.bnot(x) == (-1 - x) % 2^32) | |
| 8868 | </pre> | |
| 8869 | ||
| 8870 | ||
| 8871 | ||
| 8872 | <p> | |
| 8873 | <hr><h3><a name="pdf-bit32.bor"><code>bit32.bor (···)</code></a></h3> | |
| 8874 | ||
| 8875 | ||
| 8876 | <p> | |
| 8877 | Returns the bitwise <em>or</em> of its operands. | |
| 8878 | ||
| 8879 | ||
| 8880 | ||
| 8881 | ||
| 8882 | <p> | |
| 8883 | <hr><h3><a name="pdf-bit32.btest"><code>bit32.btest (···)</code></a></h3> | |
| 8884 | ||
| 8885 | ||
| 8886 | <p> | |
| 8887 | Returns a boolean signaling | |
| 8888 | whether the bitwise <em>and</em> of its operands is different from zero. | |
| 8889 | ||
| 8890 | ||
| 8891 | ||
| 8892 | ||
| 8893 | <p> | |
| 8894 | <hr><h3><a name="pdf-bit32.bxor"><code>bit32.bxor (···)</code></a></h3> | |
| 8895 | ||
| 8896 | ||
| 8897 | <p> | |
| 8898 | Returns the bitwise <em>exclusive or</em> of its operands. | |
| 8899 | ||
| 8900 | ||
| 8901 | ||
| 8902 | ||
| 8903 | <p> | |
| 8904 | <hr><h3><a name="pdf-bit32.extract"><code>bit32.extract (n, field [, width])</code></a></h3> | |
| 8905 | ||
| 8906 | ||
| 8907 | <p> | |
| 8908 | Returns the unsigned number formed by the bits | |
| 8909 | <code>field</code> to <code>field + width - 1</code> from <code>n</code>. | |
| 8910 | Bits are numbered from 0 (least significant) to 31 (most significant). | |
| 8911 | All accessed bits must be in the range <em>[0, 31]</em>. | |
| 8912 | ||
| 8913 | ||
| 8914 | <p> | |
| 8915 | The default for <code>width</code> is 1. | |
| 8916 | ||
| 8917 | ||
| 8918 | ||
| 8919 | ||
| 8920 | <p> | |
| 8921 | <hr><h3><a name="pdf-bit32.replace"><code>bit32.replace (n, v, field [, width])</code></a></h3> | |
| 8922 | ||
| 8923 | ||
| 8924 | <p> | |
| 8925 | Returns a copy of <code>n</code> with | |
| 8926 | the bits <code>field</code> to <code>field + width - 1</code> | |
| 8927 | replaced by the value <code>v</code>. | |
| 8928 | See <a href="#pdf-bit32.extract"><code>bit32.extract</code></a> for details about <code>field</code> and <code>width</code>. | |
| 8929 | ||
| 8930 | ||
| 8931 | ||
| 8932 | ||
| 8933 | <p> | |
| 8934 | <hr><h3><a name="pdf-bit32.lrotate"><code>bit32.lrotate (x, disp)</code></a></h3> | |
| 8935 | ||
| 8936 | ||
| 8937 | <p> | |
| 8938 | Returns the number <code>x</code> rotated <code>disp</code> bits to the left. | |
| 8939 | The number <code>disp</code> may be any representable integer. | |
| 8940 | ||
| 8941 | ||
| 8942 | <p> | |
| 8943 | For any valid displacement, | |
| 8944 | the following identity holds: | |
| 8945 | ||
| 8946 | <pre> | |
| 8947 | assert(bit32.lrotate(x, disp) == bit32.lrotate(x, disp % 32)) | |
| 8948 | </pre><p> | |
| 8949 | In particular, | |
| 8950 | negative displacements rotate to the right. | |
| 8951 | ||
| 8952 | ||
| 8953 | ||
| 8954 | ||
| 8955 | <p> | |
| 8956 | <hr><h3><a name="pdf-bit32.lshift"><code>bit32.lshift (x, disp)</code></a></h3> | |
| 8957 | ||
| 8958 | ||
| 8959 | <p> | |
| 8960 | Returns the number <code>x</code> shifted <code>disp</code> bits to the left. | |
| 8961 | The number <code>disp</code> may be any representable integer. | |
| 8962 | Negative displacements shift to the right. | |
| 8963 | In any direction, vacant bits are filled with zeros. | |
| 8964 | In particular, | |
| 8965 | displacements with absolute values higher than 31 | |
| 8966 | result in zero (all bits are shifted out). | |
| 8967 | ||
| 8968 | ||
| 8969 | <p> | |
| 8970 | For positive displacements, | |
| 8971 | the following equality holds: | |
| 8972 | ||
| 8973 | <pre> | |
| 8974 | assert(bit32.lshift(b, disp) == (b * 2^disp) % 2^32) | |
| 8975 | </pre> | |
| 8976 | ||
| 8977 | ||
| 8978 | ||
| 8979 | <p> | |
| 8980 | <hr><h3><a name="pdf-bit32.rrotate"><code>bit32.rrotate (x, disp)</code></a></h3> | |
| 8981 | ||
| 8982 | ||
| 8983 | <p> | |
| 8984 | Returns the number <code>x</code> rotated <code>disp</code> bits to the right. | |
| 8985 | The number <code>disp</code> may be any representable integer. | |
| 8986 | ||
| 8987 | ||
| 8988 | <p> | |
| 8989 | For any valid displacement, | |
| 8990 | the following identity holds: | |
| 8991 | ||
| 8992 | <pre> | |
| 8993 | assert(bit32.rrotate(x, disp) == bit32.rrotate(x, disp % 32)) | |
| 8994 | </pre><p> | |
| 8995 | In particular, | |
| 8996 | negative displacements rotate to the left. | |
| 8997 | ||
| 8998 | ||
| 8999 | ||
| 9000 | ||
| 9001 | <p> | |
| 9002 | <hr><h3><a name="pdf-bit32.rshift"><code>bit32.rshift (x, disp)</code></a></h3> | |
| 9003 | ||
| 9004 | ||
| 9005 | <p> | |
| 9006 | Returns the number <code>x</code> shifted <code>disp</code> bits to the right. | |
| 9007 | The number <code>disp</code> may be any representable integer. | |
| 9008 | Negative displacements shift to the left. | |
| 9009 | In any direction, vacant bits are filled with zeros. | |
| 9010 | In particular, | |
| 9011 | displacements with absolute values higher than 31 | |
| 9012 | result in zero (all bits are shifted out). | |
| 9013 | ||
| 9014 | ||
| 9015 | <p> | |
| 9016 | For positive displacements, | |
| 9017 | the following equality holds: | |
| 9018 | ||
| 9019 | <pre> | |
| 9020 | assert(bit32.rshift(b, disp) == math.floor(b % 2^32 / 2^disp)) | |
| 9021 | </pre> | |
| 9022 | ||
| 9023 | <p> | |
| 9024 | This shift operation is what is called logical shift. | |
| 9025 | ||
| 9026 | ||
| 9027 | ||
| 9028 | ||
| 9029 | ||
| 9030 | ||
| 9031 | ||
| 9312 | 9032 | <h2>6.8 – <a name="6.8">Input and Output Facilities</a></h2> |
| 9313 | 9033 | |
| 9314 | 9034 | <p> |
| 9315 | 9035 | The I/O library provides two different styles for file manipulation. |
| 9316 | The first one uses implicit file | |
| 9036 | The first one uses implicit file descriptors; | |
| 9317 | 9037 | that is, there are operations to set a default input file and a |
| 9318 | 9038 | default output file, |
| 9319 | 9039 | and all input/output operations are over these default files. |
| 9320 | The second style uses explicit file | |
| 9040 | The second style uses explicit file descriptors. | |
| 9321 | 9041 | |
| 9322 | 9042 | |
| 9323 | 9043 | <p> |
| 9324 | When using implicit file | |
| 9044 | When using implicit file descriptors, | |
| 9325 | 9045 | all operations are supplied by table <a name="pdf-io"><code>io</code></a>. |
| 9326 | When using explicit file handles, | |
| 9327 | the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file handle | |
| 9328 | and then all operations are supplied as methods of the file handle. | |
| 9046 | When using explicit file descriptors, | |
| 9047 | the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file descriptor | |
| 9048 | and then all operations are supplied as methods of the file descriptor. | |
| 9329 | 9049 | |
| 9330 | 9050 | |
| 9331 | 9051 | <p> |
| 9332 | 9052 | The table <code>io</code> also provides |
| 9333 | three predefined file | |
| 9053 | three predefined file descriptors with their usual meanings from C: | |
| 9334 | 9054 | <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>. |
| 9335 | 9055 | The I/O library never closes these files. |
| 9336 | 9056 | |
| r242899 | r242900 | |
| 9341 | 9061 | (plus an error message as a second result and |
| 9342 | 9062 | a system-dependent error code as a third result) |
| 9343 | 9063 | and some value different from <b>nil</b> on success. |
| 9344 | On non-P | |
| 9064 | On non-Posix systems, | |
| 9345 | 9065 | the computation of the error message and error code |
| 9346 | 9066 | in case of errors |
| 9347 | 9067 | may be not thread safe, |
| r242899 | r242900 | |
| 9398 | 9118 | and returns an iterator function that |
| 9399 | 9119 | works like <code>file:lines(···)</code> over the opened file. |
| 9400 | 9120 | When the iterator function detects the end of file, |
| 9401 | it returns n | |
| 9121 | it returns <b>nil</b> (to finish the loop) and automatically closes the file. | |
| 9402 | 9122 | |
| 9403 | 9123 | |
| 9404 | 9124 | <p> |
| 9405 | 9125 | The call <code>io.lines()</code> (with no file name) is equivalent |
| 9406 | to <code>io.input():lines( | |
| 9126 | to <code>io.input():lines()</code>; | |
| 9407 | 9127 | that is, it iterates over the lines of the default input file. |
| 9408 | 9128 | In this case it does not close the file when the loop ends. |
| 9409 | 9129 | |
| r242899 | r242900 | |
| 9556 | 9276 | each time it is called, |
| 9557 | 9277 | reads the file according to the given formats. |
| 9558 | 9278 | When no format is given, |
| 9559 | uses " | |
| 9279 | uses "*l" as a default. | |
| 9560 | 9280 | As an example, the construction |
| 9561 | 9281 | |
| 9562 | 9282 | <pre> |
| r242899 | r242900 | |
| 9583 | 9303 | Reads the file <code>file</code>, |
| 9584 | 9304 | according to the given formats, which specify what to read. |
| 9585 | 9305 | For each format, |
| 9586 | the function returns a string or a number with the characters read, | |
| 9306 | the function returns a string (or a number) with the characters read, | |
| 9587 | 9307 | or <b>nil</b> if it cannot read data with the specified format. |
| 9588 | (In this latter case, | |
| 9589 | the function does not read subsequent formats.) | |
| 9590 | 9308 | When called without formats, |
| 9591 | 9309 | it uses a default format that reads the next line |
| 9592 | 9310 | (see below). |
| r242899 | r242900 | |
| 9597 | 9315 | |
| 9598 | 9316 | <ul> |
| 9599 | 9317 | |
| 9600 | <li><b>"<code>n</code>": </b> | |
| 9601 | reads a numeral and returns it as a float or an integer, | |
| 9602 | following the lexical conventions of Lua. | |
| 9603 | (The numeral may have leading spaces and a sign.) | |
| 9604 | This format always reads the longest input sequence that | |
| 9605 | is a valid prefix for a number; | |
| 9606 | if that prefix does not form a valid number | |
| 9607 | (e.g., an empty string, "<code>0x</code>", or "<code>3.4e-</code>"), | |
| 9608 | it is discarded and the function returns <b>nil</b>. | |
| 9318 | <li><b>"<code>*n</code>": </b> | |
| 9319 | reads a number; | |
| 9320 | this is the only format that returns a number instead of a string. | |
| 9609 | 9321 | </li> |
| 9610 | 9322 | |
| 9611 | <li><b>"<code>i</code>": </b> | |
| 9612 | reads an integral number and returns it as an integer. | |
| 9613 | </li> | |
| 9614 | ||
| 9615 | <li><b>"<code>a</code>": </b> | |
| 9323 | <li><b>"<code>*a</code>": </b> | |
| 9616 | 9324 | reads the whole file, starting at the current position. |
| 9617 | 9325 | On end of file, it returns the empty string. |
| 9618 | 9326 | </li> |
| 9619 | 9327 | |
| 9620 | <li><b>"<code>l</code>": </b> | |
| 9328 | <li><b>"<code>*l</code>": </b> | |
| 9621 | 9329 | reads the next line skipping the end of line, |
| 9622 | 9330 | returning <b>nil</b> on end of file. |
| 9623 | 9331 | This is the default format. |
| 9624 | 9332 | </li> |
| 9625 | 9333 | |
| 9626 | <li><b>"<code>L</code>": </b> | |
| 9627 | reads the next line keeping the end-of-line character (if present), | |
| 9334 | <li><b>"<code>*L</code>": </b> | |
| 9335 | reads the next line keeping the end of line (if present), | |
| 9628 | 9336 | returning <b>nil</b> on end of file. |
| 9629 | 9337 | </li> |
| 9630 | 9338 | |
| 9631 | 9339 | <li><b><em>number</em>: </b> |
| 9632 | 9340 | reads a string with up to this number of bytes, |
| 9633 | 9341 | returning <b>nil</b> on end of file. |
| 9634 | If | |
| 9342 | If number is zero, | |
| 9635 | 9343 | it reads nothing and returns an empty string, |
| 9636 | 9344 | or <b>nil</b> on end of file. |
| 9637 | 9345 | </li> |
| 9638 | 9346 | |
| 9639 | </ul><p> | |
| 9640 | The formats "<code>l</code>" and "<code>L</code>" should be used only for text files. | |
| 9347 | </ul> | |
| 9641 | 9348 | |
| 9642 | 9349 | |
| 9643 | 9350 | |
| 9644 | ||
| 9645 | 9351 | <p> |
| 9646 | 9352 | <hr><h3><a name="pdf-file:seek"><code>file:seek ([whence [, offset]])</code></a></h3> |
| 9647 | 9353 | |
| r242899 | r242900 | |
| 9780 | 9486 | <p> |
| 9781 | 9487 | If <code>format</code> is not "<code>*t</code>", |
| 9782 | 9488 | then <code>date</code> returns the date as a string, |
| 9783 | formatted according to the same rules as the | |
| 9489 | formatted according to the same rules as the ANSI C function <code>strftime</code>. | |
| 9784 | 9490 | |
| 9785 | 9491 | |
| 9786 | 9492 | <p> |
| r242899 | r242900 | |
| 9791 | 9497 | |
| 9792 | 9498 | |
| 9793 | 9499 | <p> |
| 9794 | On non-P | |
| 9500 | On non-Posix systems, | |
| 9795 | 9501 | this function may be not thread safe |
| 9796 | 9502 | because of its reliance on C function <code>gmtime</code> and C function <code>localtime</code>. |
| 9797 | 9503 | |
| r242899 | r242900 | |
| 9803 | 9509 | |
| 9804 | 9510 | |
| 9805 | 9511 | <p> |
| 9806 | Returns the difference, in seconds, | |
| 9807 | from time <code>t1</code> to time <code>t2</code> | |
| 9808 | (where the times are values returned by <a href="#pdf-os.time"><code>os.time</code></a>). | |
| 9512 | Returns the number of seconds from time <code>t1</code> to time <code>t2</code>. | |
| 9809 | 9513 | In POSIX, Windows, and some other systems, |
| 9810 | 9514 | this value is exactly <code>t2</code><em>-</em><code>t1</code>. |
| 9811 | 9515 | |
| r242899 | r242900 | |
| 9817 | 9521 | |
| 9818 | 9522 | |
| 9819 | 9523 | <p> |
| 9820 | This function is equivalent to the | |
| 9524 | This function is equivalent to the ANSI C function <code>system</code>. | |
| 9821 | 9525 | It passes <code>command</code> to be executed by an operating system shell. |
| 9822 | 9526 | Its first result is <b>true</b> |
| 9823 | 9527 | if the command terminated successfully, |
| 9824 | 9528 | or <b>nil</b> otherwise. |
| 9825 | 9529 | After this first result |
| 9826 | the function returns a string | |
| 9530 | the function returns a string and a number, | |
| 9827 | 9531 | as follows: |
| 9828 | 9532 | |
| 9829 | 9533 | <ul> |
| r242899 | r242900 | |
| 9848 | 9552 | |
| 9849 | 9553 | |
| 9850 | 9554 | <p> |
| 9851 | <hr><h3><a name="pdf-os.exit"><code>os.exit ([code [, close] | |
| 9555 | <hr><h3><a name="pdf-os.exit"><code>os.exit ([code [, close])</code></a></h3> | |
| 9852 | 9556 | |
| 9853 | 9557 | |
| 9854 | 9558 | <p> |
| 9855 | Calls the | |
| 9559 | Calls the ANSI C function <code>exit</code> to terminate the host program. | |
| 9856 | 9560 | If <code>code</code> is <b>true</b>, |
| 9857 | 9561 | the returned status is <code>EXIT_SUCCESS</code>; |
| 9858 | 9562 | if <code>code</code> is <b>false</b>, |
| r242899 | r242900 | |
| 10115 | 9819 | |
| 10116 | 9820 | <p> |
| 10117 | 9821 | The first parameter or local variable has index 1, and so on, |
| 10118 | following the order that they are declared in the code, | |
| 10119 | counting only the variables that are active | |
| 10120 | in the current scope of the function. | |
| 9822 | until the last active variable. | |
| 10121 | 9823 | Negative indices refer to vararg parameters; |
| 10122 | 9824 | -1 is the first vararg parameter. |
| 10123 | 9825 | The function returns <b>nil</b> if there is no variable with the given index, |
| r242899 | r242900 | |
| 10126 | 9828 | |
| 10127 | 9829 | |
| 10128 | 9830 | <p> |
| 10129 | Variable names starting with '<code>(</code>' (open parenthesis) | |
| 10130 | represent variables with no known names | |
| 10131 | (internal variables such as loop control variables, | |
| 10132 | and variables from chunks saved without debug information). | |
| 9831 | Variable names starting with '<code>(</code>' (open parenthesis) | |
| 9832 | represent internal variables | |
| 9833 | (loop control variables, temporaries, varargs, and C function locals). | |
| 10133 | 9834 | |
| 10134 | 9835 | |
| 10135 | 9836 | <p> |
| r242899 | r242900 | |
| 10170 | 9871 | The function returns <b>nil</b> if there is no upvalue with the given index. |
| 10171 | 9872 | |
| 10172 | 9873 | |
| 10173 | <p> | |
| 10174 | Variable names starting with '<code>(</code>' (open parenthesis) | |
| 10175 | represent variables with no known names | |
| 10176 | (variables from chunks saved without debug information). | |
| 10177 | 9874 | |
| 10178 | 9875 | |
| 10179 | ||
| 10180 | ||
| 10181 | 9876 | <p> |
| 10182 | 9877 | <hr><h3><a name="pdf-debug.getuservalue"><code>debug.getuservalue (u)</code></a></h3> |
| 10183 | 9878 | |
| r242899 | r242900 | |
| 10198 | 9893 | Sets the given function as a hook. |
| 10199 | 9894 | The string <code>mask</code> and the number <code>count</code> describe |
| 10200 | 9895 | when the hook will be called. |
| 10201 | The string mask may have | |
| 9896 | The string mask may have the following characters, | |
| 10202 | 9897 | with the given meaning: |
| 10203 | 9898 | |
| 10204 | 9899 | <ul> |
| r242899 | r242900 | |
| 10206 | 9901 | <li><b>'<code>r</code>': </b> the hook is called every time Lua returns from a function;</li> |
| 10207 | 9902 | <li><b>'<code>l</code>': </b> the hook is called every time Lua enters a new line of code.</li> |
| 10208 | 9903 | </ul><p> |
| 10209 | Moreover, | |
| 10210 | with a <code>count</code> different from zero, | |
| 10211 | the hook is called also after every <code>count</code> instructions. | |
| 9904 | With a <code>count</code> different from zero, | |
| 9905 | the hook is called after every <code>count</code> instructions. | |
| 10212 | 9906 | |
| 10213 | 9907 | |
| 10214 | 9908 | <p> |
| r242899 | r242900 | |
| 10287 | 9981 | <p> |
| 10288 | 9982 | Sets the given <code>value</code> as |
| 10289 | 9983 | the Lua value associated to the given <code>udata</code>. |
| 9984 | <code>value</code> must be a table or <b>nil</b>; | |
| 10290 | 9985 | <code>udata</code> must be a full userdata. |
| 10291 | 9986 | |
| 10292 | 9987 | |
| r242899 | r242900 | |
| 10305 | 10000 | this function returns <code>message</code> without further processing. |
| 10306 | 10001 | Otherwise, |
| 10307 | 10002 | it returns a string with a traceback of the call stack. |
| 10308 | ||
| 10003 | An optional <code>message</code> string is appended | |
| 10309 | 10004 | at the beginning of the traceback. |
| 10310 | 10005 | An optional <code>level</code> number tells at which level |
| 10311 | 10006 | to start the traceback |
| r242899 | r242900 | |
| 10319 | 10014 | |
| 10320 | 10015 | |
| 10321 | 10016 | <p> |
| 10322 | Returns a unique identifier (as a light userdata) | |
| 10017 | Returns an unique identifier (as a light userdata) | |
| 10323 | 10018 | for the upvalue numbered <code>n</code> |
| 10324 | 10019 | from the given function. |
| 10325 | 10020 | |
| r242899 | r242900 | |
| 10375 | 10070 | <li><b><code>--</code>: </b> stops handling options;</li> |
| 10376 | 10071 | <li><b><code>-</code>: </b> executes <code>stdin</code> as a file and stops handling options.</li> |
| 10377 | 10072 | </ul><p> |
| 10378 | After handling its options, <code>lua</code> runs the given <em>script</em>. | |
| 10073 | After handling its options, <code>lua</code> runs the given <em>script</em>, | |
| 10074 | passing to it the given <em>args</em> as string arguments. | |
| 10379 | 10075 | When called without arguments, |
| 10380 | 10076 | <code>lua</code> behaves as <code>lua -v -i</code> |
| 10381 | 10077 | when the standard input (<code>stdin</code>) is a terminal, |
| r242899 | r242900 | |
| 10384 | 10080 | |
| 10385 | 10081 | <p> |
| 10386 | 10082 | When called without option <code>-E</code>, |
| 10387 | the interpreter checks for an environment variable <a name="pdf-LUA_INIT_5_3"><code>LUA_INIT_5_3</code></a> | |
| 10388 | (or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if the versioned name is not defined) | |
| 10083 | the interpreter checks for an environment variable <a name="pdf-LUA_INIT_5_2"><code>LUA_INIT_5_2</code></a> | |
| 10084 | (or <a name="pdf-LUA_INIT"><code>LUA_INIT</code></a> if it is not defined) | |
| 10389 | 10085 | before running any argument. |
| 10390 | 10086 | If the variable content has the format <code>@<em>filename</em></code>, |
| 10391 | 10087 | then <code>lua</code> executes the file. |
| r242899 | r242900 | |
| 10415 | 10111 | |
| 10416 | 10112 | |
| 10417 | 10113 | <p> |
| 10418 | Before running any code, | |
| 10419 | <code>lua</code> collects all command-line arguments | |
| 10114 | Before starting to run the script, | |
| 10115 | <code>lua</code> collects all arguments in the command line | |
| 10420 | 10116 | in a global table called <code>arg</code>. |
| 10421 | The script name | |
| 10117 | The script name is stored at index 0, | |
| 10422 | 10118 | the first argument after the script name goes to index 1, |
| 10423 | 10119 | and so on. |
| 10424 | 10120 | Any arguments before the script name |
| 10425 | (that is, the interpreter name plus | |
| 10121 | (that is, the interpreter name plus the options) | |
| 10426 | 10122 | go to negative indices. |
| 10427 | 10123 | For instance, in the call |
| 10428 | 10124 | |
| 10429 | 10125 | <pre> |
| 10430 | 10126 | $ lua -la b.lua t1 t2 |
| 10431 | 10127 | </pre><p> |
| 10432 | the table is like this: | |
| 10128 | the interpreter first runs the file <code>a.lua</code>, | |
| 10129 | then creates a table | |
| 10433 | 10130 | |
| 10434 | 10131 | <pre> |
| 10435 | 10132 | arg = { [-2] = "lua", [-1] = "-la", |
| 10436 | 10133 | [0] = "b.lua", |
| 10437 | 10134 | [1] = "t1", [2] = "t2" } |
| 10438 | 10135 | </pre><p> |
| 10439 | If there is no script in the call, | |
| 10440 | the interpreter name goes to index 0, | |
| 10441 | followed by the other arguments. | |
| 10442 | For instance, the call | |
| 10136 | and finally runs the file <code>b.lua</code>. | |
| 10137 | The script is called with <code>arg[1]</code>, <code>arg[2]</code>, ... | |
| 10138 | as arguments; | |
| 10139 | it can also access these arguments with the vararg expression '<code>...</code>'. | |
| 10443 | 10140 | |
| 10444 | <pre> | |
| 10445 | $ lua -e "print(arg[1])" | |
| 10446 | </pre><p> | |
| 10447 | will print "<code>-e</code>". | |
| 10448 | If there is a script, | |
| 10449 | the script is called with parameters | |
| 10450 | <code>arg[1]</code>, ···, <code>arg[#arg]</code>. | |
| 10451 | (Like all chunks in Lua, | |
| 10452 | the script is compiled as a vararg function.) | |
| 10453 | 10141 | |
| 10454 | ||
| 10455 | 10142 | <p> |
| 10456 | 10143 | In interactive mode, |
| 10457 | Lua repeatedly prompts and waits for a line. | |
| 10458 | After reading a line, | |
| 10459 | Lua first try to interpret the line as an expression. | |
| 10460 | If it succeeds, it prints its value. | |
| 10461 | Otherwise, it interprets the line as a statement. | |
| 10462 | If you write an incomplete statement, | |
| 10144 | if you write an incomplete statement, | |
| 10463 | 10145 | the interpreter waits for its completion |
| 10464 | 10146 | by issuing a different prompt. |
| 10465 | 10147 | |
| r242899 | r242900 | |
| 10467 | 10149 | <p> |
| 10468 | 10150 | In case of unprotected errors in the script, |
| 10469 | 10151 | the interpreter reports the error to the standard error stream. |
| 10470 | If the error object is not a string but | |
| 10471 | has a metamethod <code>__tostring</code>, | |
| 10152 | If the error object is a string, | |
| 10153 | the interpreter adds a stack traceback to it. | |
| 10154 | Otherwise, if the error object has a metamethod <code>__tostring</code>, | |
| 10472 | 10155 | the interpreter calls this metamethod to produce the final message. |
| 10473 | Otherwise, the interpreter converts the error object to a string | |
| 10474 | and adds a stack traceback to it. | |
| 10156 | Finally, if the error object is <b>nil</b>, | |
| 10157 | the interpreter does not report the error. | |
| 10475 | 10158 | |
| 10476 | 10159 | |
| 10477 | 10160 | <p> |
| r242899 | r242900 | |
| 10510 | 10193 | |
| 10511 | 10194 | <p> |
| 10512 | 10195 | Here we list the incompatibilities that you may find when moving a program |
| 10513 | from Lua 5. | |
| 10196 | from Lua 5.1 to Lua 5.2. | |
| 10514 | 10197 | You can avoid some incompatibilities by compiling Lua with |
| 10515 | 10198 | appropriate options (see file <code>luaconf.h</code>). |
| 10516 | 10199 | However, |
| 10517 | all these compatibility options will be removed in the future. | |
| 10200 | all these compatibility options will be removed in the next version of Lua. | |
| 10201 | Similarly, | |
| 10202 | all features marked as deprecated in Lua 5.1 | |
| 10203 | have been removed in Lua 5.2. | |
| 10518 | 10204 | |
| 10519 | 10205 | |
| 10520 | <p> | |
| 10521 | Lua versions can always change the C API in ways that | |
| 10522 | do not imply source-code changes in a program, | |
| 10523 | such as the numeric values for constants | |
| 10524 | or the implementation of functions as macros. | |
| 10525 | Therefore, | |
| 10526 | you should not assume that binaries are compatible between | |
| 10527 | different Lua versions. | |
| 10528 | Always recompile clients of the Lua API when | |
| 10529 | using a new version. | |
| 10530 | 10206 | |
| 10207 | <h2>8.1 – <a name="8.1">Changes in the Language</a></h2> | |
| 10208 | <ul> | |
| 10531 | 10209 | |
| 10532 | <p> | |
| 10533 | Similarly, Lua versions can always change the internal representation | |
| 10534 | of precompiled chunks; | |
| 10535 | precompiled chunks are not compatible between different Lua versions. | |
| 10210 | <li> | |
| 10211 | The concept of <em>environment</em> changed. | |
| 10212 | Only Lua functions have environments. | |
| 10213 | To set the environment of a Lua function, | |
| 10214 | use the variable <code>_ENV</code> or the function <a href="#pdf-load"><code>load</code></a>. | |
| 10536 | 10215 | |
| 10537 | 10216 | |
| 10538 | 10217 | <p> |
| 10539 | The standard paths in the official distribution may | |
| 10540 | change between versions. | |
| 10218 | C functions no longer have environments. | |
| 10219 | Use an upvalue with a shared table if you need to keep | |
| 10220 | shared state among several C functions. | |
| 10221 | (You may use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> to open a C library | |
| 10222 | with all functions sharing a common upvalue.) | |
| 10541 | 10223 | |
| 10542 | 10224 | |
| 10225 | <p> | |
| 10226 | To manipulate the "environment" of a userdata | |
| 10227 | (which is now called user value), | |
| 10228 | use the new functions | |
| 10229 | <a href="#lua_getuservalue"><code>lua_getuservalue</code></a> and <a href="#lua_setuservalue"><code>lua_setuservalue</code></a>. | |
| 10230 | </li> | |
| 10543 | 10231 | |
| 10544 | <h2>8.1 – <a name="8.1">Changes in the Language</a></h2> | |
| 10545 | <ul> | |
| 10546 | ||
| 10547 | 10232 | <li> |
| 10548 | The main difference between Lua 5.2 and Lua 5.3 is the | |
| 10549 | introduction of an integer subtype for numbers. | |
| 10550 | Although this change should not affect "normal" computations, | |
| 10551 | some computations | |
| 10552 | (mainly those that involve some kind of overflow) | |
| 10553 | can give different results. | |
| 10233 | Lua identifiers cannot use locale-dependent letters. | |
| 10234 | </li> | |
| 10554 | 10235 | |
| 10555 | ||
| 10556 | <p> | |
| 10557 | You can fix these differences by forcing a number to be a float | |
| 10558 | (in Lua 5.2 all numbers were float), | |
| 10559 | in particular writing constants with an ending <code>.0</code> | |
| 10560 | or using <code>x = x + 0.0</code> to convert a variable. | |
| 10561 | (This recommendation is only for a quick fix | |
| 10562 | for an occasional incompatibility; | |
| 10563 | it is not a general guideline for good programming. | |
| 10564 | For good programming, | |
| 10565 | use floats where you need floats | |
| 10566 | and integers where you need integers.) | |
| 10236 | <li> | |
| 10237 | Doing a step or a full collection in the garbage collector | |
| 10238 | does not restart the collector if it has been stopped. | |
| 10567 | 10239 | </li> |
| 10568 | 10240 | |
| 10569 | 10241 | <li> |
| 10570 | The conversion of a float to a string now adds a <code>.0</code> suffix | |
| 10571 | to the result if it looks like an integer. | |
| 10572 | (For instance, the float 2.0 will be printed as <code>2.0</code>, | |
| 10573 | not as <code>2</code>.) | |
| 10574 | You should always use an explicit format | |
| 10575 | when you need a specific format for numbers. | |
| 10242 | Weak tables with weak keys now perform like <em>ephemeron tables</em>. | |
| 10243 | </li> | |
| 10576 | 10244 | |
| 10577 | ||
| 10578 | <p> | |
| 10579 | (Formally this is not an incompatibility, | |
| 10580 | because Lua does not specify how numbers are formatted as strings, | |
| 10581 | but some programs assumed a specific format.) | |
| 10245 | <li> | |
| 10246 | The event <em>tail return</em> in debug hooks was removed. | |
| 10247 | Instead, tail calls generate a special new event, | |
| 10248 | <em>tail call</em>, so that the debugger can know that | |
| 10249 | there will not be a corresponding return event. | |
| 10582 | 10250 | </li> |
| 10583 | 10251 | |
| 10584 | 10252 | <li> |
| 10585 | The generational mode for the garbage collector was removed. | |
| 10586 | (It was an experimental feature in Lua 5.2.) | |
| 10253 | Equality between function values has changed. | |
| 10254 | Now, a function definition may not create a new value; | |
| 10255 | it may reuse some previous value if there is no | |
| 10256 | observable difference to the new function. | |
| 10587 | 10257 | </li> |
| 10588 | 10258 | |
| 10589 | 10259 | </ul> |
| r242899 | r242900 | |
| 10595 | 10265 | <ul> |
| 10596 | 10266 | |
| 10597 | 10267 | <li> |
| 10598 | The <code>bit32</code> library has been deprecated. | |
| 10599 | It is easy to require a compatible external library or, | |
| 10600 | better yet, to replace its functions with appropriate bitwise operations. | |
| 10601 | (Keep in mind that <code>bit32</code> operates on 32-bit integers, | |
| 10602 | while the bitwise operators in standard Lua operate on 64-bit integers.) | |
| 10268 | Function <code>module</code> is deprecated. | |
| 10269 | It is easy to set up a module with regular Lua code. | |
| 10270 | Modules are not expected to set global variables. | |
| 10603 | 10271 | </li> |
| 10604 | 10272 | |
| 10605 | 10273 | <li> |
| 10606 | The Table library now respects metamethods | |
| 10607 | for setting and getting elements. | |
| 10274 | Functions <code>setfenv</code> and <code>getfenv</code> were removed, | |
| 10275 | because of the changes in environments. | |
| 10608 | 10276 | </li> |
| 10609 | 10277 | |
| 10610 | 10278 | <li> |
| 10611 | The <a href="#pdf-ipairs"><code>ipairs</code></a> iterator now respects metamethods and | |
| 10612 | its <code>__ipairs</code> metamethod has been deprecated. | |
| 10279 | Function <code>math.log10</code> is deprecated. | |
| 10280 | Use <a href="#pdf-math.log"><code>math.log</code></a> with 10 as its second argument, instead. | |
| 10613 | 10281 | </li> |
| 10614 | 10282 | |
| 10615 | 10283 | <li> |
| 10616 | Option names in <a href="#pdf-io.read"><code>io.read</code></a> do not have a starting '<code>*</code>' anymore. | |
| 10617 | For compatibility, Lua will continue to ignore this character. | |
| 10284 | Function <code>loadstring</code> is deprecated. | |
| 10285 | Use <code>load</code> instead; it now accepts string arguments | |
| 10286 | and are exactly equivalent to <code>loadstring</code>. | |
| 10618 | 10287 | </li> |
| 10619 | 10288 | |
| 10620 | 10289 | <li> |
| 10621 | The following functions were deprecated in the mathematical library: | |
| 10622 | <code>atan2</code>, <code>cosh</code>, <code>sinh</code>, <code>tanh</code>, <code>pow</code>, | |
| 10623 | <code>frexp</code>, and <code>ldexp</code>. | |
| 10624 | You can replace <code>math.pow(x,y)</code> with <code>x^y</code>; | |
| 10625 | you can replace <code>math.atan2</code> with <code>math.atan</code>, | |
| 10626 | which now accepts one or two parameters; | |
| 10627 | you can replace <code>math.ldexp(x,exp)</code> with <code>x * 2.0^exp</code>. | |
| 10628 | For the other operations, | |
| 10629 | you can either use an external library or | |
| 10630 | implement them in Lua. | |
| 10290 | Function <code>table.maxn</code> is deprecated. | |
| 10291 | Write it in Lua if you really need it. | |
| 10631 | 10292 | </li> |
| 10632 | 10293 | |
| 10633 | 10294 | <li> |
| 10634 | The searcher for C loaders used by <a href="#pdf-require"><code>require</code></a> | |
| 10635 | changed the way it handles versioned names. | |
| 10636 | Now, the version should come after the module name | |
| 10637 | (as is usual in most other tools). | |
| 10638 | For compatibility, that searcher still tries the old format | |
| 10639 | if it cannot find an open function according to the new style. | |
| 10640 | (Lua 5.2 already worked that way, | |
| 10641 | but it did not document the change.) | |
| 10295 | Function <code>os.execute</code> now returns <b>true</b> when command | |
| 10296 | terminates successfully and <b>nil</b> plus error information | |
| 10297 | otherwise. | |
| 10642 | 10298 | </li> |
| 10643 | 10299 | |
| 10300 | <li> | |
| 10301 | Function <code>unpack</code> was moved into the table library | |
| 10302 | and therefore must be called as <a href="#pdf-table.unpack"><code>table.unpack</code></a>. | |
| 10303 | </li> | |
| 10304 | ||
| 10305 | <li> | |
| 10306 | Character class <code>%z</code> in patterns is deprecated, | |
| 10307 | as now patterns may contain '<code>\0</code>' as a regular character. | |
| 10308 | </li> | |
| 10309 | ||
| 10310 | <li> | |
| 10311 | The table <code>package.loaders</code> was renamed <code>package.searchers</code>. | |
| 10312 | </li> | |
| 10313 | ||
| 10314 | <li> | |
| 10315 | Lua does not have bytecode verification anymore. | |
| 10316 | So, all functions that load code | |
| 10317 | (<a href="#pdf-load"><code>load</code></a> and <a href="#pdf-loadfile"><code>loadfile</code></a>) | |
| 10318 | are potentially insecure when loading untrusted binary data. | |
| 10319 | (Actually, those functions were already insecure because | |
| 10320 | of flaws in the verification algorithm.) | |
| 10321 | When in doubt, | |
| 10322 | use the <code>mode</code> argument of those functions | |
| 10323 | to restrict them to loading textual chunks. | |
| 10324 | </li> | |
| 10325 | ||
| 10326 | <li> | |
| 10327 | The standard paths in the official distribution may | |
| 10328 | change between versions. | |
| 10329 | </li> | |
| 10330 | ||
| 10644 | 10331 | </ul> |
| 10645 | 10332 | |
| 10646 | 10333 | |
| 10647 | 10334 | |
| 10648 | 10335 | |
| 10649 | 10336 | <h2>8.3 – <a name="8.3">Changes in the API</a></h2> |
| 10337 | <ul> | |
| 10650 | 10338 | |
| 10339 | <li> | |
| 10340 | Pseudoindex <code>LUA_GLOBALSINDEX</code> was removed. | |
| 10341 | You must get the global environment from the registry | |
| 10342 | (see <a href="#4.5">§4.5</a>). | |
| 10343 | </li> | |
| 10651 | 10344 | |
| 10652 | <ul> | |
| 10345 | <li> | |
| 10346 | Pseudoindex <code>LUA_ENVIRONINDEX</code> | |
| 10347 | and functions <code>lua_getfenv</code>/<code>lua_setfenv</code> | |
| 10348 | were removed, | |
| 10349 | as C functions no longer have environments. | |
| 10350 | </li> | |
| 10653 | 10351 | |
| 10654 | 10352 | <li> |
| 10655 | Continuation functions now receive as parameters what they needed | |
| 10656 | to get through <code>lua_getctx</code>, | |
| 10657 | so <code>lua_getctx</code> has been removed. | |
| 10658 | Adapt your code accordingly. | |
| 10353 | Function <code>luaL_register</code> is deprecated. | |
| 10354 | Use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> so that your module does not create globals. | |
| 10355 | (Modules are not expected to set global variables anymore.) | |
| 10659 | 10356 | </li> |
| 10660 | 10357 | |
| 10661 | 10358 | <li> |
| 10662 | Function <a href="#lua_dump"><code>lua_dump</code></a> has an extra parameter, <code>strip</code>. | |
| 10663 | Use 0 as the value of this parameter to get the old behavior. | |
| 10359 | The <code>osize</code> argument to the allocation function | |
| 10360 | may not be zero when creating a new block, | |
| 10361 | that is, when <code>ptr</code> is <code>NULL</code> | |
| 10362 | (see <a href="#lua_Alloc"><code>lua_Alloc</code></a>). | |
| 10363 | Use only the test <code>ptr == NULL</code> to check whether | |
| 10364 | the block is new. | |
| 10664 | 10365 | </li> |
| 10665 | 10366 | |
| 10666 | 10367 | <li> |
| 10667 | Functions to inject/project unsigned integers | |
| 10668 | (<code>lua_pushunsigned</code>, <code>lua_tounsigned</code>, <code>lua_tounsignedx</code>, | |
| 10669 | <code>luaL_checkunsigned</code>, <code>luaL_optunsigned</code>) | |
| 10670 | were deprecated. | |
| 10671 | Use their signed equivalents with a type cast. | |
| 10368 | Finalizers (<code>__gc</code> metamethods) for userdata are called in the | |
| 10369 | reverse order that they were marked for finalization, | |
| 10370 | not that they were created (see <a href="#2.5.1">§2.5.1</a>). | |
| 10371 | (Most userdata are marked immediately after they are created.) | |
| 10372 | Moreover, | |
| 10373 | if the metatable does not have a <code>__gc</code> field when set, | |
| 10374 | the finalizer will not be called, | |
| 10375 | even if it is set later. | |
| 10672 | 10376 | </li> |
| 10673 | 10377 | |
| 10674 | 10378 | <li> |
| 10675 | Macros to project non-default integer types | |
| 10676 | (<code>luaL_checkint</code>, <code>luaL_optint</code>, <code>luaL_checklong</code>, <code>luaL_optlong</code>) | |
| 10677 | were deprecated. | |
| 10678 | Use their equivalent over <a href="#lua_Integer"><code>lua_Integer</code></a> with a type cast | |
| 10679 | (or, when possible, use <a href="#lua_Integer"><code>lua_Integer</code></a> in your code). | |
| 10379 | <code>luaL_typerror</code> was removed. | |
| 10380 | Write your own version if you need it. | |
| 10680 | 10381 | </li> |
| 10681 | 10382 | |
| 10383 | <li> | |
| 10384 | Function <code>lua_cpcall</code> is deprecated. | |
| 10385 | You can simply push the function with <a href="#lua_pushcfunction"><code>lua_pushcfunction</code></a> | |
| 10386 | and call it with <a href="#lua_pcall"><code>lua_pcall</code></a>. | |
| 10387 | </li> | |
| 10388 | ||
| 10389 | <li> | |
| 10390 | Functions <code>lua_equal</code> and <code>lua_lessthan</code> are deprecated. | |
| 10391 | Use the new <a href="#lua_compare"><code>lua_compare</code></a> with appropriate options instead. | |
| 10392 | </li> | |
| 10393 | ||
| 10394 | <li> | |
| 10395 | Function <code>lua_objlen</code> was renamed <a href="#lua_rawlen"><code>lua_rawlen</code></a>. | |
| 10396 | </li> | |
| 10397 | ||
| 10398 | <li> | |
| 10399 | Function <a href="#lua_load"><code>lua_load</code></a> has an extra parameter, <code>mode</code>. | |
| 10400 | Pass <code>NULL</code> to simulate the old behavior. | |
| 10401 | </li> | |
| 10402 | ||
| 10403 | <li> | |
| 10404 | Function <a href="#lua_resume"><code>lua_resume</code></a> has an extra parameter, <code>from</code>. | |
| 10405 | Pass <code>NULL</code> or the thread doing the call. | |
| 10406 | </li> | |
| 10407 | ||
| 10682 | 10408 | </ul> |
| 10683 | 10409 | |
| 10684 | 10410 | |
| r242899 | r242900 | |
| 10688 | 10414 | |
| 10689 | 10415 | <p> |
| 10690 | 10416 | Here is the complete syntax of Lua in extended BNF. |
| 10691 | As usual in extended BNF, | |
| 10692 | {A} means 0 or more As, | |
| 10693 | and [A] means an optional A. | |
| 10694 | (For operator precedences, see <a href="#3.4.8">§3.4.8</a>; | |
| 10695 | for a description of the terminals | |
| 10696 | Name, Numeral, | |
| 10697 | and LiteralString, see <a href="#3.1">§3.1</a>.) | |
| 10417 | (It does not describe operator precedences.) | |
| 10698 | 10418 | |
| 10699 | 10419 | |
| 10700 | 10420 | |
| r242899 | r242900 | |
| 10735 | 10455 | |
| 10736 | 10456 | explist ::= exp {‘<b>,</b>’ exp} |
| 10737 | 10457 | |
| 10738 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Numer | |
| 10458 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | ‘<b>...</b>’ | functiondef | | |
| 10739 | 10459 | prefixexp | tableconstructor | exp binop exp | unop exp |
| 10740 | 10460 | |
| 10741 | 10461 | prefixexp ::= var | functioncall | ‘<b>(</b>’ exp ‘<b>)</b>’ |
| 10742 | 10462 | |
| 10743 | 10463 | functioncall ::= prefixexp args | prefixexp ‘<b>:</b>’ Name args |
| 10744 | 10464 | |
| 10745 | args ::= ‘<b>(</b>’ [explist] ‘<b>)</b>’ | tableconstructor | | |
| 10465 | args ::= ‘<b>(</b>’ [explist] ‘<b>)</b>’ | tableconstructor | String | |
| 10746 | 10466 | |
| 10747 | 10467 | functiondef ::= <b>function</b> funcbody |
| 10748 | 10468 | |
| r242899 | r242900 | |
| 10758 | 10478 | |
| 10759 | 10479 | fieldsep ::= ‘<b>,</b>’ | ‘<b>;</b>’ |
| 10760 | 10480 | |
| 10761 | binop ::= ‘<b>+</b>’ | ‘<b>-</b>’ | ‘<b>*</b>’ | ‘<b>/</b>’ | ‘<b>//</b>’ | ‘<b>^</b>’ | ‘<b>%</b>’ | | |
| 10762 | ‘<b>&</b>’ | ‘<b>~</b>’ | ‘<b>|</b>’ | ‘<b>>></b>’ | ‘<b><<</b>’ | ‘<b>..</b>’ | | |
| 10481 | binop ::= ‘<b>+</b>’ | ‘<b>-</b>’ | ‘<b>*</b>’ | ‘<b>/</b>’ | ‘<b>^</b>’ | ‘<b>%</b>’ | ‘<b>..</b>’ | | |
| 10763 | 10482 | ‘<b><</b>’ | ‘<b><=</b>’ | ‘<b>></b>’ | ‘<b>>=</b>’ | ‘<b>==</b>’ | ‘<b>~=</b>’ | |
| 10764 | 10483 | <b>and</b> | <b>or</b> |
| 10765 | 10484 | |
| 10766 | unop ::= ‘<b>-</b>’ | <b>not</b> | ‘<b>#</b>’ | |
| 10485 | unop ::= ‘<b>-</b>’ | <b>not</b> | ‘<b>#</b>’ | |
| 10767 | 10486 | |
| 10768 | 10487 | </pre> |
| 10769 | 10488 | |
| r242899 | r242900 | |
| 10775 | 10494 | |
| 10776 | 10495 | |
| 10777 | 10496 | |
| 10778 | ||
| 10779 | 10497 | <HR> |
| 10780 | 10498 | <SMALL CLASS="footer"> |
| 10781 | 10499 | Last update: |
| 10782 | Tu | |
| 10500 | Thu Mar 21 12:58:59 BRT 2013 | |
| 10783 | 10501 | </SMALL> |
| 10784 | 10502 | <!-- |
| 10785 | Last change: revised for Lua 5. | |
| 10503 | Last change: revised for Lua 5.2.2 | |
| 10786 | 10504 | --> |
| 10787 | 10505 | |
| 10788 | 10506 | </body></html> |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| 2 | 2 | <HTML> |
| 3 | 3 | <HEAD> |
| 4 | <TITLE>Lua 5. | |
| 4 | <TITLE>Lua 5.2 readme</TITLE> | |
| 5 | 5 | <LINK REL="stylesheet" TYPE="text/css" HREF="lua.css"> |
| 6 | 6 | <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1"> |
| 7 | 7 | <STYLE TYPE="text/css"> |
| 8 | 8 | blockquote, .display { |
| 9 | 9 | border: solid #a0a0a0 2px ; |
| 10 | border-radius: 8px ; | |
| 10 | 11 | padding: 1em ; |
| 11 | 12 | margin: 0px ; |
| 12 | border-radius: 8px ; | |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | .display { |
| r242899 | r242900 | |
| 31 | 31 | <HR> |
| 32 | 32 | <H1> |
| 33 | 33 | <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A> |
| 34 | Welcome to Lua 5. | |
| 34 | Welcome to Lua 5.2 | |
| 35 | 35 | </H1> |
| 36 | 36 | |
| 37 | 37 | <P> |
| r242899 | r242900 | |
| 70 | 70 | updated |
| 71 | 71 | <A HREF="http://www.lua.org/docs.html">documentation</A>, |
| 72 | 72 | especially the |
| 73 | <A HREF="http://www.lua.org/manual/5. | |
| 73 | <A HREF="http://www.lua.org/manual/5.2/">reference manual</A>, | |
| 74 | 74 | which may differ slightly from the |
| 75 | 75 | <A HREF="contents.html">local copy</A> |
| 76 | 76 | distributed in this package. |
| r242899 | r242900 | |
| 98 | 98 | get a binary from |
| 99 | 99 | <A HREF="http://lua-users.org/wiki/LuaBinaries">LuaBinaries</A>. |
| 100 | 100 | Try also |
| 101 | <A HREF="http://luadist.org/">LuaDist</A>, | |
| 102 | a multi-platform distribution of Lua that includes batteries. | |
| 101 | <A HREF="http://luaforwindows.luaforge.net/">Lua for Windows</A>, | |
| 102 | an easy-to-use distribution of Lua that includes many useful libraries. | |
| 103 | 103 | |
| 104 | 104 | <H3>Building Lua</H3> |
| 105 | 105 | |
| r242899 | r242900 | |
| 110 | 110 | <OL> |
| 111 | 111 | <LI> |
| 112 | 112 | Open a terminal window and move to |
| 113 | the top-level directory, which is named <TT>lua-5.3.0</TT>. | |
| 114 | The <TT>Makefile</TT> there controls both the build process and the installation process. | |
| 113 | the top-level directory, which is named <TT>lua-5.2.3</TT>. | |
| 114 | The Makefile there controls both the build process and the installation process. | |
| 115 | 115 | <P> |
| 116 | 116 | <LI> |
| 117 | 117 | Do "<KBD>make</KBD>" and see if your platform is listed. |
| 118 | 118 | The platforms currently supported are: |
| 119 | 119 | <P> |
| 120 | 120 | <P CLASS="display"> |
| 121 | aix bsd | |
| 121 | aix ansi bsd freebsd generic linux macosx mingw posix solaris | |
| 122 | 122 | </P> |
| 123 | 123 | <P> |
| 124 | 124 | If your platform is listed, just do "<KBD>make xxx</KBD>", where xxx |
| 125 | 125 | is your platform name. |
| 126 | 126 | <P> |
| 127 | 127 | If your platform is not listed, try the closest one or posix, generic, |
| 128 | | |
| 128 | ansi, in this order. | |
| 129 | 129 | <P> |
| 130 | 130 | <LI> |
| 131 | 131 | The compilation takes only a few moments |
| r242899 | r242900 | |
| 136 | 136 | <P> |
| 137 | 137 | <LI> |
| 138 | 138 | To check that Lua has been built correctly, do "<KBD>make test</KBD>" |
| 139 | after building Lua. This will run the interpreter and print its version. | |
| 139 | after building Lua. This will run the interpreter and print its version string. | |
| 140 | 140 | </OL> |
| 141 | 141 | <P> |
| 142 | 142 | If you're running Linux and get compilation errors, |
| r242899 | r242900 | |
| 148 | 148 | <P> |
| 149 | 149 | Once you have built Lua, you may want to install it in an official |
| 150 | 150 | place in your system. In this case, do "<KBD>make install</KBD>". The official |
| 151 | place and the way to install files are defined in the | |
| 151 | place and the way to install files are defined in the Makefile. You'll | |
| 152 | 152 | probably need the right permissions to install files. |
| 153 | 153 | |
| 154 | 154 | <P> |
| r242899 | r242900 | |
| 158 | 158 | <P> |
| 159 | 159 | To install Lua locally, do "<KBD>make local</KBD>". |
| 160 | 160 | This will create a directory <TT>install</TT> with subdirectories |
| 161 | <TT>bin</TT>, <TT>include</TT>, <TT>lib</TT>, <TT>man</TT>, | |
| 161 | <TT>bin</TT>, <TT>include</TT>, <TT>lib</TT>, <TT>man</TT>, | |
| 162 | 162 | and install Lua as listed below. |
| 163 | 163 | |
| 164 | 164 | To install Lua locally, but in some other directory, do |
| 165 | 165 | "<KBD>make install INSTALL_TOP=xxx</KBD>", where xxx is your chosen directory. |
| 166 | The installation starts in the <TT>src</TT> and <TT>doc</TT> directories, | |
| 167 | so take care if <TT>INSTALL_TOP</TT> is not an absolute path. | |
| 168 | 166 | |
| 169 | 167 | <DL CLASS="display"> |
| 170 | 168 | <DT> |
| r242899 | r242900 | |
| 174 | 172 | <DT> |
| 175 | 173 | include: |
| 176 | 174 | <DD> |
| 177 | l | |
| 175 | lua.h luaconf.h lualib.h lauxlib.h lua.hpp | |
| 178 | 176 | <DT> |
| 179 | 177 | lib: |
| 180 | 178 | <DD> |
| r242899 | r242900 | |
| 188 | 186 | <P> |
| 189 | 187 | These are the only directories you need for development. |
| 190 | 188 | If you only want to run Lua programs, |
| 191 | you only need the files in <TT>bin</TT> and <TT>man</TT>. | |
| 192 | The files in <TT>include</TT> and <TT>lib</TT> are needed for | |
| 189 | you only need the files in bin and man. | |
| 190 | The files in include and lib are needed for | |
| 193 | 191 | embedding Lua in C or C++ programs. |
| 194 | 192 | |
| 195 | 193 | <H3><A NAME="customization">Customization</A></H3> |
| r242899 | r242900 | |
| 205 | 203 | You don't actually need to edit the Makefiles because you may set the |
| 206 | 204 | relevant variables in the command line when invoking make. |
| 207 | 205 | Nevertheless, it's probably best to edit and save the Makefiles to |
| 208 | record the changes you | |
| 206 | record the changes you need. | |
| 209 | 207 | |
| 210 | 208 | <P> |
| 211 | 209 | On the other hand, if you need to customize some Lua features, you'll need |
| r242899 | r242900 | |
| 214 | 212 | it will be used by any Lua clients that you build, to ensure consistency. |
| 215 | 213 | Further customization is available to experts by editing the Lua sources. |
| 216 | 214 | |
| 215 | <P> | |
| 216 | We strongly recommend that you enable dynamic loading in <TT>src/luaconf.h</TT>. | |
| 217 | This is done automatically for all platforms listed above that have | |
| 218 | this feature and also for Windows. | |
| 219 | ||
| 217 | 220 | <H3><A NAME="other">Building Lua on other systems</A></H3> |
| 218 | 221 | |
| 219 | 222 | <P> |
| r242899 | r242900 | |
| 230 | 233 | lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c |
| 231 | 234 | ltm.c lundump.c lvm.c lzio.c |
| 232 | 235 | lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c |
| 233 | lmathlib.c loslib.c lstrlib.c ltablib.c l | |
| 236 | lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c | |
| 234 | 237 | <DT> |
| 235 | 238 | interpreter: |
| 236 | 239 | <DD> |
| r242899 | r242900 | |
| 251 | 254 | be linked statically into the host program and its symbols exported for |
| 252 | 255 | dynamic linking; <TT>src/Makefile</TT> does this for the Lua interpreter. |
| 253 | 256 | For Windows, we recommend that the Lua library be a DLL. |
| 254 | In all cases, the compiler luac should be linked statically. | |
| 255 | 257 | |
| 256 | 258 | <P> |
| 257 | 259 | As mentioned above, you may edit <TT>src/luaconf.h</TT> to customize |
| 258 | 260 | some features before building Lua. |
| 259 | 261 | |
| 260 | <H2><A NAME="changes">Changes since Lua 5. | |
| 262 | <H2><A NAME="changes">Changes since Lua 5.1</A></H2> | |
| 261 | 263 | |
| 262 | 264 | <P> |
| 263 | Here are the main changes introduced in Lua 5. | |
| 265 | Here are the main changes introduced in Lua 5.2. | |
| 264 | 266 | The |
| 265 | 267 | <A HREF="contents.html">reference manual</A> |
| 266 | 268 | lists the |
| r242899 | r242900 | |
| 268 | 270 | |
| 269 | 271 | <H3>Main changes</H3> |
| 270 | 272 | <UL> |
| 271 | <LI> integers (64-bit by default) | |
| 272 | <LI> official support for 32-bit numbers | |
| 273 | <LI> bitwise operators | |
| 274 | <LI> basic utf-8 support | |
| 275 | <LI> functions for packing and unpacking values | |
| 276 | ||
| 273 | <LI> yieldable pcall and metamethods | |
| 274 | <LI> new lexical scheme for globals | |
| 275 | <LI> ephemeron tables | |
| 276 | <LI> new library for bitwise operations | |
| 277 | <LI> light C functions | |
| 278 | <LI> emergency garbage collector | |
| 279 | <LI> <CODE>goto</CODE> statement | |
| 280 | <LI> finalizers for tables | |
| 277 | 281 | </UL> |
| 278 | 282 | |
| 279 | Here are the other changes introduced in Lua 5. | |
| 283 | Here are the other changes introduced in Lua 5.2: | |
| 280 | 284 | <H3>Language</H3> |
| 281 | 285 | <UL> |
| 282 | <LI> userdata can have any Lua value as uservalue | |
| 283 | <LI> integer division | |
| 284 | <LI> more flexible rules for some metamethods | |
| 286 | <LI> no more fenv for threads or functions | |
| 287 | <LI> tables honor the <CODE>__len</CODE> metamethod | |
| 288 | <LI> hex and <CODE>\z</CODE> escapes in strings | |
| 289 | <LI> support for hexadecimal floats | |
| 290 | <LI> order metamethods work for different types | |
| 291 | <LI> no more verification of opcode consistency | |
| 292 | <LI> hook event "tail return" replaced by "tail call" | |
| 293 | <LI> empty statement | |
| 294 | <LI> <CODE>break</CODE> statement may appear in the middle of a block | |
| 285 | 295 | </UL> |
| 286 | 296 | |
| 287 | 297 | <H3>Libraries</H3> |
| 288 | 298 | <UL> |
| 289 | <LI> <CODE>ipairs</CODE> and the table library respect metamethods | |
| 290 | <LI> strip option in <CODE>string.dump</CODE> | |
| 291 | <LI> table library respects metamethods | |
| 292 | <LI> new function <CODE>table.move</CODE> | |
| 293 | <LI> new function <CODE>string.pack</CODE> | |
| 294 | <LI> new function <CODE>string.unpack</CODE> | |
| 295 | <LI> new function <CODE>string.packsize</CODE> | |
| 299 | <LI> arguments for function called through <CODE>xpcall</CODE> | |
| 300 | <LI> optional 'mode' argument to load and loadfile (to control binary x text) | |
| 301 | <LI> optional 'env' argument to load and loadfile (environment for loaded chunk) | |
| 302 | <LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL) | |
| 303 | <LI> new function <CODE>package.searchpath</CODE> | |
| 304 | <LI> modules receive their paths when loaded | |
| 305 | <LI> optional base in <CODE>math.log</CODE> | |
| 306 | <LI> optional separator in <CODE>string.rep</CODE> | |
| 307 | <LI> <CODE>file:write</CODE> returns <CODE>file</CODE> | |
| 308 | <LI> closing a pipe returns exit status | |
| 309 | <LI> <CODE>os.exit</CODE> may close state | |
| 310 | <LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE> | |
| 311 | <LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE> | |
| 312 | <LI> frontier patterns | |
| 313 | <LI> <CODE>\0</CODE> in patterns | |
| 314 | <LI> new option <CODE>*L</CODE> for <CODE>io.read</CODE> | |
| 315 | <LI> options for <CODE>io.lines</CODE> | |
| 316 | <LI> <CODE>debug.getlocal</CODE> can access function varargs | |
| 296 | 317 | </UL> |
| 297 | 318 | |
| 298 | 319 | <H3>C API</H3> |
| 299 | 320 | <UL> |
| 300 | <LI> simpler API for continuation functions in C | |
| 301 | <LI> <CODE>lua_gettable</CODE> and similar functions return type of resulted value | |
| 302 | <LI> strip option in <CODE>lua_dump</CODE> | |
| 303 | <LI> new function: <CODE>lua_geti</CODE> | |
| 304 | <LI> new function: <CODE>lua_seti</CODE> | |
| 305 | <LI> new function: <CODE>lua_isyieldable</CODE> | |
| 306 | <LI> new function: <CODE>lua_numbertointeger</CODE> | |
| 307 | <LI> new function: <CODE>lua_rotate</CODE> | |
| 308 | <LI> new function: <CODE>lua_stringtonumber</CODE> | |
| 321 | <LI> main thread predefined in the registry | |
| 322 | <LI> new functions | |
| 323 | <CODE>lua_absindex</CODE>, | |
| 324 | <CODE>lua_arith</CODE>, | |
| 325 | <CODE>lua_compare</CODE>, | |
| 326 | <CODE>lua_copy</CODE>, | |
| 327 | <CODE>lua_len</CODE>, | |
| 328 | <CODE>lua_rawgetp</CODE>, | |
| 329 | <CODE>lua_rawsetp</CODE>, | |
| 330 | <CODE>lua_upvalueid</CODE>, | |
| 331 | <CODE>lua_upvaluejoin</CODE>, | |
| 332 | <CODE>lua_version</CODE>. | |
| 333 | <LI> new functions | |
| 334 | <CODE>luaL_checkversion</CODE>, | |
| 335 | <CODE>luaL_setmetatable</CODE>, | |
| 336 | <CODE>luaL_testudata</CODE>, | |
| 337 | <CODE>luaL_tolstring</CODE>. | |
| 338 | <LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string | |
| 339 | <LI> <CODE>nparams</CODE> and <CODE>isvararg</CODE> available in debug API | |
| 340 | <LI> new <CODE>lua_Unsigned</CODE> | |
| 309 | 341 | </UL> |
| 310 | 342 | |
| 343 | <H3>Implementation</H3> | |
| 344 | <UL> | |
| 345 | <LI> max constants per function raised to 2<SUP>26</SUP> | |
| 346 | <LI> generational mode for garbage collection (experimental) | |
| 347 | <LI> NaN trick (experimental) | |
| 348 | <LI> internal (immutable) version of ctypes | |
| 349 | <LI> simpler implementation for string buffers | |
| 350 | <LI> parser uses much less C-stack space (no more auto arrays) | |
| 351 | </UL> | |
| 352 | ||
| 311 | 353 | <H3>Lua standalone interpreter</H3> |
| 312 | 354 | <UL> |
| 313 | <LI> can be used as calculator; no need to prefix with '=' | |
| 314 | <LI> <CODE>arg</CODE> table available to all code | |
| 355 | <LI> new <CODE>-E</CODE> option to avoid environment variables | |
| 356 | <LI> handling of non-string error messages | |
| 315 | 357 | </UL> |
| 316 | 358 | |
| 317 | 359 | <H2><A NAME="license">License</A></H2> |
| r242899 | r242900 | |
| 333 | 375 | <A HREF="http://www.lua.org/license.html">this</A>. |
| 334 | 376 | |
| 335 | 377 | <BLOCKQUOTE STYLE="padding-bottom: 0em"> |
| 336 | Copyright © 1994–201 | |
| 378 | Copyright © 1994–2013 Lua.org, PUC-Rio. | |
| 337 | 379 | |
| 338 | 380 | <P> |
| 339 | 381 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| r242899 | r242900 | |
| 361 | 403 | <HR> |
| 362 | 404 | <SMALL CLASS="footer"> |
| 363 | 405 | Last update: |
| 364 | ||
| 406 | Sat Nov 9 22:39:16 BRST 2013 | |
| 365 | 407 | </SMALL> |
| 366 | 408 | <!-- |
| 367 | Last change: | |
| 409 | Last change: revised for Lua 5.2.3 | |
| 368 | 410 | --> |
| 369 | 411 | |
| 370 | 412 | </BODY> |
| r242899 | r242900 | |
|---|---|---|
| 6 | 6 | # Your platform. See PLATS for possible values. |
| 7 | 7 | PLAT= none |
| 8 | 8 | |
| 9 | CC= gcc -std=gnu99 | |
| 10 | CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS) | |
| 9 | CC= gcc | |
| 10 | CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) | |
| 11 | 11 | LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) |
| 12 | 12 | LIBS= -lm $(SYSLIBS) $(MYLIBS) |
| 13 | 13 | |
| r242899 | r242900 | |
| 26 | 26 | |
| 27 | 27 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= |
| 28 | 28 | |
| 29 | PLATS= aix bsd | |
| 29 | PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris | |
| 30 | 30 | |
| 31 | 31 | LUA_A= liblua.a |
| 32 | 32 | CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ |
| 33 | 33 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ |
| 34 | 34 | ltm.o lundump.o lvm.o lzio.o |
| 35 | 35 | LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ |
| 36 | lmathlib.o loslib.o lstrlib.o ltablib.o l | |
| 36 | lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o | |
| 37 | 37 | BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) |
| 38 | 38 | |
| 39 | 39 | LUA_T= lua |
| r242899 | r242900 | |
| 91 | 91 | aix: |
| 92 | 92 | $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" |
| 93 | 93 | |
| 94 | ansi: | |
| 95 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" | |
| 96 | ||
| 94 | 97 | bsd: |
| 95 | 98 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" |
| 96 | 99 | |
| 97 | c89: | |
| 98 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89" | |
| 99 | @echo '' | |
| 100 | @echo '*** C89 does not guarantee 64-bit integers for Lua.' | |
| 101 | @echo '' | |
| 102 | ||
| 103 | ||
| 104 | 100 | freebsd: |
| 105 | 101 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" |
| 106 | 102 | |
| r242899 | r242900 | |
| 113 | 109 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc |
| 114 | 110 | |
| 115 | 111 | mingw: |
| 116 | $(MAKE) "LUA_A=lua5 | |
| 112 | $(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \ | |
| 117 | 113 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ |
| 118 | 114 | "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe |
| 119 | 115 | $(MAKE) "LUAC_T=luac.exe" luac.exe |
| r242899 | r242900 | |
| 122 | 118 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" |
| 123 | 119 | |
| 124 | 120 | solaris: |
| 125 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN | |
| 121 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" | |
| 126 | 122 | |
| 127 | 123 | # list targets that do not create files (but not all makes understand .PHONY) |
| 128 | 124 | .PHONY: all $(PLATS) default o a clean depend echo none |
| 129 | 125 | |
| 130 | 126 | # DO NOT DELETE |
| 131 | 127 | |
| 132 | lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ | |
| 133 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ | |
| 134 | ltable.h lundump.h lvm.h | |
| 135 | lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h | |
| 136 | lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 137 | lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 138 | lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ | |
| 139 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ | |
| 140 | ldo.h lgc.h lstring.h ltable.h lvm.h | |
| 141 | lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 142 | lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h | |
| 143 | ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 144 | ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ | |
| 145 | lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ | |
| 146 | ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h | |
| 147 | ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ | |
| 148 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \ | |
| 149 | lparser.h lstring.h ltable.h lundump.h lvm.h | |
| 150 | ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \ | |
| 151 | ltm.h lzio.h lmem.h lundump.h | |
| 152 | lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \ | |
| 153 | lgc.h lstate.h ltm.h lzio.h lmem.h | |
| 154 | lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ | |
| 155 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h | |
| 156 | linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h | |
| 157 | liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 158 | llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldo.h \ | |
| 159 | lobject.h lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h \ | |
| 160 | ltable.h | |
| 161 | lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 162 | lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ | |
| 163 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h | |
| 164 | loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 165 | lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \ | |
| 166 | ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ | |
| 167 | lvm.h | |
| 168 | lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h | |
| 169 | loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 170 | lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ | |
| 171 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ | |
| 172 | ldo.h lfunc.h lstring.h lgc.h ltable.h | |
| 173 | lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ | |
| 174 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ | |
| 175 | lstring.h ltable.h | |
| 176 | lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ | |
| 177 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h | |
| 178 | lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 179 | ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ | |
| 180 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h | |
| 181 | ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 182 | ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ | |
| 183 | llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h | |
| 184 | lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 185 | luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \ | |
| 186 | lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h | |
| 187 | lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ | |
| 188 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ | |
| 189 | lundump.h | |
| 190 | lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h | |
| 191 | lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ | |
| 192 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ | |
| 193 | ltable.h lvm.h | |
| 194 | lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \ | |
| 195 | lobject.h ltm.h lzio.h | |
| 128 | lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ | |
| 129 | lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \ | |
| 130 | lvm.h | |
| 131 | lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h | |
| 132 | lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h | |
| 133 | lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h | |
| 134 | lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ | |
| 135 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ | |
| 136 | lstring.h ltable.h lvm.h | |
| 137 | lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h | |
| 138 | lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h | |
| 139 | ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h | |
| 140 | ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ | |
| 141 | ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \ | |
| 142 | lfunc.h lstring.h lgc.h ltable.h lvm.h | |
| 143 | ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ | |
| 144 | lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ | |
| 145 | lstring.h ltable.h lundump.h lvm.h | |
| 146 | ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ | |
| 147 | lzio.h lmem.h lundump.h | |
| 148 | lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ | |
| 149 | lstate.h ltm.h lzio.h lmem.h | |
| 150 | lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ | |
| 151 | lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.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 | |
| 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 | |
| 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 \ | |
| 158 | ltm.h lzio.h lmem.h ldo.h lgc.h | |
| 159 | loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h | |
| 160 | lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \ | |
| 161 | lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h | |
| 162 | lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h | |
| 163 | loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h | |
| 164 | lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ | |
| 165 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \ | |
| 166 | lstring.h lgc.h ltable.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 \ | |
| 169 | ltable.h | |
| 170 | lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ | |
| 171 | ltm.h lzio.h lstring.h lgc.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 \ | |
| 174 | ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h | |
| 175 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h | |
| 176 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ | |
| 177 | lmem.h lstring.h lgc.h ltable.h | |
| 178 | lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h | |
| 179 | luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.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 \ | |
| 182 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h | |
| 183 | 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.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ | |
| 186 | lzio.h | |
| 196 | 187 | |
| 197 | # (end of Makefile) |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lapi.c,v 2. | |
| 2 | ** $Id: lapi.c,v 2.171.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lua API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lapi_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <stdarg.h> |
| 14 | 9 | #include <string.h> |
| 15 | 10 | |
| 11 | #define lapi_c | |
| 12 | #define LUA_CORE | |
| 13 | ||
| 16 | 14 | #include "lua.h" |
| 17 | 15 | |
| 18 | 16 | #include "lapi.h" |
| r242899 | r242900 | |
| 45 | 43 | /* test for pseudo index */ |
| 46 | 44 | #define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) |
| 47 | 45 | |
| 48 | /* test for upvalue */ | |
| 49 | #define isupvalue(i) ((i) < LUA_REGISTRYINDEX) | |
| 50 | ||
| 51 | 46 | /* test for valid but not pseudo index */ |
| 52 | 47 | #define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) |
| 53 | 48 | |
| 54 | #define api_checkvalidindex(o) api_check(isvalid(o), "invalid index") | |
| 49 | #define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index") | |
| 55 | 50 | |
| 56 | #define api_checkstackindex(i, o) \ | |
| 57 | api_check(isstackindex(i, o), "index not in the stack") | |
| 51 | #define api_checkstackindex(L, i, o) \ | |
| 52 | api_check(L, isstackindex(i, o), "index not in the stack") | |
| 58 | 53 | |
| 59 | 54 | |
| 60 | 55 | static TValue *index2addr (lua_State *L, int idx) { |
| 61 | 56 | CallInfo *ci = L->ci; |
| 62 | 57 | if (idx > 0) { |
| 63 | 58 | TValue *o = ci->func + idx; |
| 64 | api_check(idx <= ci->top - (ci->func + 1), "unacceptable index"); | |
| 59 | api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); | |
| 65 | 60 | if (o >= L->top) return NONVALIDVALUE; |
| 66 | 61 | else return o; |
| 67 | 62 | } |
| 68 | 63 | else if (!ispseudo(idx)) { /* negative index */ |
| 69 | api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); | |
| 64 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); | |
| 70 | 65 | return L->top + idx; |
| 71 | 66 | } |
| 72 | 67 | else if (idx == LUA_REGISTRYINDEX) |
| 73 | 68 | return &G(L)->l_registry; |
| 74 | 69 | else { /* upvalues */ |
| 75 | 70 | idx = LUA_REGISTRYINDEX - idx; |
| 76 | api_check(idx <= MAXUPVAL + 1, "upvalue index too large"); | |
| 71 | api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); | |
| 77 | 72 | if (ttislcf(ci->func)) /* light C function? */ |
| 78 | 73 | return NONVALIDVALUE; /* it has no upvalues */ |
| 79 | 74 | else { |
| r242899 | r242900 | |
| 94 | 89 | } |
| 95 | 90 | |
| 96 | 91 | |
| 97 | LUA_API int lua_checkstack (lua_State *L, int | |
| 92 | LUA_API int lua_checkstack (lua_State *L, int size) { | |
| 98 | 93 | int res; |
| 99 | 94 | CallInfo *ci = L->ci; |
| 100 | 95 | lua_lock(L); |
| 101 | api_check(n >= 0, "negative 'n'"); | |
| 102 | if (L->stack_last - L->top > n) /* stack large enough? */ | |
| 96 | if (L->stack_last - L->top > size) /* stack large enough? */ | |
| 103 | 97 | res = 1; /* yes; check is OK */ |
| 104 | 98 | else { /* no; need to grow stack */ |
| 105 | 99 | int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; |
| 106 | if (inuse > LUAI_MAXSTACK - | |
| 100 | if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */ | |
| 107 | 101 | res = 0; /* no */ |
| 108 | 102 | else /* try to grow stack */ |
| 109 | res = (luaD_rawrunprotected(L, &growstack, & | |
| 103 | res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK); | |
| 110 | 104 | } |
| 111 | if (res && ci->top < L->top + n) | |
| 112 | ci->top = L->top + n; /* adjust frame top */ | |
| 105 | if (res && ci->top < L->top + size) | |
| 106 | ci->top = L->top + size; /* adjust frame top */ | |
| 113 | 107 | lua_unlock(L); |
| 114 | 108 | return res; |
| 115 | 109 | } |
| r242899 | r242900 | |
| 120 | 114 | if (from == to) return; |
| 121 | 115 | lua_lock(to); |
| 122 | 116 | api_checknelems(from, n); |
| 123 | api_check(G(from) == G(to), "moving among independent states"); | |
| 124 | api_check(to->ci->top - to->top >= n, "not enough elements to move"); | |
| 117 | api_check(from, G(from) == G(to), "moving among independent states"); | |
| 118 | api_check(from, to->ci->top - to->top >= n, "not enough elements to move"); | |
| 125 | 119 | from->top -= n; |
| 126 | 120 | for (i = 0; i < n; i++) { |
| 127 | 121 | setobj2s(to, to->top++, from->top + i); |
| r242899 | r242900 | |
| 172 | 166 | StkId func = L->ci->func; |
| 173 | 167 | lua_lock(L); |
| 174 | 168 | if (idx >= 0) { |
| 175 | api_check(idx <= L->stack_last - (func + 1), "new top too large"); | |
| 169 | api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); | |
| 176 | 170 | while (L->top < (func + 1) + idx) |
| 177 | 171 | setnilvalue(L->top++); |
| 178 | 172 | L->top = (func + 1) + idx; |
| 179 | 173 | } |
| 180 | 174 | else { |
| 181 | api_check(-(idx+1) <= (L->top - (func + 1)), "invalid new top"); | |
| 182 | L->top += idx+1; /* 'subtract' index (index is negative) */ | |
| 175 | api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); | |
| 176 | L->top += idx+1; /* `subtract' index (index is negative) */ | |
| 183 | 177 | } |
| 184 | 178 | lua_unlock(L); |
| 185 | 179 | } |
| 186 | 180 | |
| 187 | 181 | |
| 188 | /* | |
| 189 | ** Reverse the stack segment from 'from' to 'to' | |
| 190 | ** (auxiliary to 'lua_rotate') | |
| 191 | */ | |
| 192 | static void reverse (lua_State *L, StkId from, StkId to) { | |
| 193 | for (; from < to; from++, to--) { | |
| 194 | TValue temp; | |
| 195 | setobj(L, &temp, from); | |
| 196 | setobjs2s(L, from, to); | |
| 197 | setobj2s(L, to, &temp); | |
| 198 | } | |
| 182 | LUA_API void lua_remove (lua_State *L, int idx) { | |
| 183 | StkId p; | |
| 184 | lua_lock(L); | |
| 185 | p = index2addr(L, idx); | |
| 186 | api_checkstackindex(L, idx, p); | |
| 187 | while (++p < L->top) setobjs2s(L, p-1, p); | |
| 188 | L->top--; | |
| 189 | lua_unlock(L); | |
| 199 | 190 | } |
| 200 | 191 | |
| 201 | 192 | |
| 202 | /* | |
| 203 | ** Let x = AB, where A is a prefix of length 'n'. Then, | |
| 204 | ** rotate x n == BA. But BA == (A^r . B^r)^r. | |
| 205 | */ | |
| 206 | LUA_API void lua_rotate (lua_State *L, int idx, int n) { | |
| 207 | StkId p, t, m; | |
| 193 | LUA_API void lua_insert (lua_State *L, int idx) { | |
| 194 | StkId p; | |
| 195 | StkId q; | |
| 208 | 196 | lua_lock(L); |
| 209 | t = L->top - 1; /* end of stack segment being rotated */ | |
| 210 | p = index2addr(L, idx); /* start of segment */ | |
| 211 | api_checkstackindex(idx, p); | |
| 212 | api_check((n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'"); | |
| 213 | m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */ | |
| 214 | reverse(L, p, m); /* reverse the prefix with length 'n' */ | |
| 215 | reverse(L, m + 1, t); /* reverse the suffix */ | |
| 216 | reverse(L, p, t); /* reverse the entire segment */ | |
| 197 | p = index2addr(L, idx); | |
| 198 | api_checkstackindex(L, idx, p); | |
| 199 | for (q = L->top; q > p; q--) /* use L->top as a temporary */ | |
| 200 | setobjs2s(L, q, q - 1); | |
| 201 | setobjs2s(L, p, L->top); | |
| 217 | 202 | lua_unlock(L); |
| 218 | 203 | } |
| 219 | 204 | |
| 220 | 205 | |
| 221 | LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { | |
| 222 | TValue *fr, *to; | |
| 223 | lua_lock(L); | |
| 224 | fr = index2addr(L, fromidx); | |
| 225 | to = index2addr(L, toidx); | |
| 226 | api_checkvalidindex(to); | |
| 206 | static void moveto (lua_State *L, TValue *fr, int idx) { | |
| 207 | TValue *to = index2addr(L, idx); | |
| 208 | api_checkvalidindex(L, to); | |
| 227 | 209 | setobj(L, to, fr); |
| 228 | if (i | |
| 210 | if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ | |
| 229 | 211 | luaC_barrier(L, clCvalue(L->ci->func), fr); |
| 230 | 212 | /* LUA_REGISTRYINDEX does not need gc barrier |
| 231 | 213 | (collector revisits it before finishing collection) */ |
| 214 | } | |
| 215 | ||
| 216 | ||
| 217 | LUA_API void lua_replace (lua_State *L, int idx) { | |
| 218 | lua_lock(L); | |
| 219 | api_checknelems(L, 1); | |
| 220 | moveto(L, L->top - 1, idx); | |
| 221 | L->top--; | |
| 232 | 222 | lua_unlock(L); |
| 233 | 223 | } |
| 234 | 224 | |
| 235 | 225 | |
| 226 | LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { | |
| 227 | TValue *fr; | |
| 228 | lua_lock(L); | |
| 229 | fr = index2addr(L, fromidx); | |
| 230 | moveto(L, fr, toidx); | |
| 231 | lua_unlock(L); | |
| 232 | } | |
| 233 | ||
| 234 | ||
| 236 | 235 | LUA_API void lua_pushvalue (lua_State *L, int idx) { |
| 237 | 236 | lua_lock(L); |
| 238 | 237 | setobj2s(L, L->top, index2addr(L, idx)); |
| r242899 | r242900 | |
| 249 | 248 | |
| 250 | 249 | LUA_API int lua_type (lua_State *L, int idx) { |
| 251 | 250 | StkId o = index2addr(L, idx); |
| 252 | return (isvalid(o) ? ttn | |
| 251 | return (isvalid(o) ? ttypenv(o) : LUA_TNONE); | |
| 253 | 252 | } |
| 254 | 253 | |
| 255 | 254 | |
| 256 | 255 | LUA_API const char *lua_typename (lua_State *L, int t) { |
| 257 | 256 | UNUSED(L); |
| 258 | api_check(LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag"); | |
| 259 | 257 | return ttypename(t); |
| 260 | 258 | } |
| 261 | 259 | |
| r242899 | r242900 | |
| 266 | 264 | } |
| 267 | 265 | |
| 268 | 266 | |
| 269 | LUA_API int lua_isinteger (lua_State *L, int idx) { | |
| 270 | StkId o = index2addr(L, idx); | |
| 271 | return ttisinteger(o); | |
| 272 | } | |
| 273 | ||
| 274 | ||
| 275 | 267 | LUA_API int lua_isnumber (lua_State *L, int idx) { |
| 276 | lu | |
| 268 | TValue n; | |
| 277 | 269 | const TValue *o = index2addr(L, idx); |
| 278 | 270 | return tonumber(o, &n); |
| 279 | 271 | } |
| 280 | 272 | |
| 281 | 273 | |
| 282 | 274 | LUA_API int lua_isstring (lua_State *L, int idx) { |
| 283 | const TValue *o = index2addr(L, idx); | |
| 284 | return (ttisstring(o) || cvt2str(o)); | |
| 275 | int t = lua_type(L, idx); | |
| 276 | return (t == LUA_TSTRING || t == LUA_TNUMBER); | |
| 285 | 277 | } |
| 286 | 278 | |
| 287 | 279 | |
| 288 | 280 | LUA_API int lua_isuserdata (lua_State *L, int idx) { |
| 289 | 281 | const TValue *o = index2addr(L, idx); |
| 290 | return (ttis | |
| 282 | return (ttisuserdata(o) || ttislightuserdata(o)); | |
| 291 | 283 | } |
| 292 | 284 | |
| 293 | 285 | |
| r242899 | r242900 | |
| 299 | 291 | |
| 300 | 292 | |
| 301 | 293 | LUA_API void lua_arith (lua_State *L, int op) { |
| 294 | StkId o1; /* 1st operand */ | |
| 295 | StkId o2; /* 2nd operand */ | |
| 302 | 296 | lua_lock(L); |
| 303 | if (op != LUA_OPUNM && op != LUA_OPBNOT) | |
| 304 | api_checknelems(L, 2); /* all other operations expect two operands */ | |
| 305 | else { /* for unary operations, add fake 2nd operand */ | |
| 297 | if (op != LUA_OPUNM) /* all other operations expect two operands */ | |
| 298 | api_checknelems(L, 2); | |
| 299 | else { /* for unary minus, add fake 2nd operand */ | |
| 306 | 300 | api_checknelems(L, 1); |
| 307 | 301 | setobjs2s(L, L->top, L->top - 1); |
| 308 | 302 | L->top++; |
| 309 | 303 | } |
| 310 | /* first operand at top - 2, second at top - 1; result go to top - 2 */ | |
| 311 | luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2); | |
| 312 | L->top--; /* remove second operand */ | |
| 304 | o1 = L->top - 2; | |
| 305 | o2 = L->top - 1; | |
| 306 | if (ttisnumber(o1) && ttisnumber(o2)) { | |
| 307 | setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2))); | |
| 308 | } | |
| 309 | else | |
| 310 | luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); | |
| 311 | L->top--; | |
| 313 | 312 | lua_unlock(L); |
| 314 | 313 | } |
| 315 | 314 | |
| r242899 | r242900 | |
| 322 | 321 | o2 = index2addr(L, index2); |
| 323 | 322 | if (isvalid(o1) && isvalid(o2)) { |
| 324 | 323 | switch (op) { |
| 325 | case LUA_OPEQ: i = | |
| 324 | case LUA_OPEQ: i = equalobj(L, o1, o2); break; | |
| 326 | 325 | case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; |
| 327 | 326 | case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; |
| 328 | default: api_check(0, "invalid option"); | |
| 327 | default: api_check(L, 0, "invalid option"); | |
| 329 | 328 | } |
| 330 | 329 | } |
| 331 | 330 | lua_unlock(L); |
| r242899 | r242900 | |
| 333 | 332 | } |
| 334 | 333 | |
| 335 | 334 | |
| 336 | LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { | |
| 337 | size_t sz = luaO_str2num(s, L->top); | |
| 338 | if (sz != 0) | |
| 339 | api_incr_top(L); | |
| 340 | return sz; | |
| 335 | LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) { | |
| 336 | TValue n; | |
| 337 | const TValue *o = index2addr(L, idx); | |
| 338 | if (tonumber(o, &n)) { | |
| 339 | if (isnum) *isnum = 1; | |
| 340 | return nvalue(o); | |
| 341 | } | |
| 342 | else { | |
| 343 | if (isnum) *isnum = 0; | |
| 344 | return 0; | |
| 345 | } | |
| 341 | 346 | } |
| 342 | 347 | |
| 343 | 348 | |
| 344 | LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { | |
| 345 | lua_Number n; | |
| 349 | LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { | |
| 350 | TValue n; | |
| 346 | 351 | const TValue *o = index2addr(L, idx); |
| 347 | int isnum = tonumber(o, &n); | |
| 348 | if (!isnum) | |
| 349 | n = 0; /* call to 'tonumber' may change 'n' even if it fails */ | |
| 350 | if (pisnum) *pisnum = isnum; | |
| 351 | return n; | |
| 352 | if (tonumber(o, &n)) { | |
| 353 | lua_Integer res; | |
| 354 | lua_Number num = nvalue(o); | |
| 355 | lua_number2integer(res, num); | |
| 356 | if (isnum) *isnum = 1; | |
| 357 | return res; | |
| 358 | } | |
| 359 | else { | |
| 360 | if (isnum) *isnum = 0; | |
| 361 | return 0; | |
| 362 | } | |
| 352 | 363 | } |
| 353 | 364 | |
| 354 | 365 | |
| 355 | LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { | |
| 356 | lua_Integer res; | |
| 366 | LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { | |
| 367 | TValue n; | |
| 357 | 368 | const TValue *o = index2addr(L, idx); |
| 358 | int isnum = tointeger(o, &res); | |
| 359 | if (!isnum) | |
| 360 | res = 0; /* call to 'tointeger' may change 'n' even if it fails */ | |
| 361 | if (pisnum) *pisnum = isnum; | |
| 362 | return res; | |
| 369 | if (tonumber(o, &n)) { | |
| 370 | lua_Unsigned res; | |
| 371 | lua_Number num = nvalue(o); | |
| 372 | lua_number2unsigned(res, num); | |
| 373 | if (isnum) *isnum = 1; | |
| 374 | return res; | |
| 375 | } | |
| 376 | else { | |
| 377 | if (isnum) *isnum = 0; | |
| 378 | return 0; | |
| 379 | } | |
| 363 | 380 | } |
| 364 | 381 | |
| 365 | 382 | |
| r242899 | r242900 | |
| 372 | 389 | LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { |
| 373 | 390 | StkId o = index2addr(L, idx); |
| 374 | 391 | if (!ttisstring(o)) { |
| 375 | if (!cvt2str(o)) { /* not convertible? */ | |
| 392 | lua_lock(L); /* `luaV_tostring' may create a new string */ | |
| 393 | if (!luaV_tostring(L, o)) { /* conversion failed? */ | |
| 376 | 394 | if (len != NULL) *len = 0; |
| 395 | lua_unlock(L); | |
| 377 | 396 | return NULL; |
| 378 | 397 | } |
| 379 | lua_lock(L); /* 'luaO_tostring' may create a new string */ | |
| 380 | 398 | luaC_checkGC(L); |
| 381 | 399 | o = index2addr(L, idx); /* previous call may reallocate the stack */ |
| 382 | luaO_tostring(L, o); | |
| 383 | 400 | lua_unlock(L); |
| 384 | 401 | } |
| 385 | 402 | if (len != NULL) *len = tsvalue(o)->len; |
| r242899 | r242900 | |
| 389 | 406 | |
| 390 | 407 | LUA_API size_t lua_rawlen (lua_State *L, int idx) { |
| 391 | 408 | StkId o = index2addr(L, idx); |
| 392 | switch (ttn | |
| 409 | switch (ttypenv(o)) { | |
| 393 | 410 | case LUA_TSTRING: return tsvalue(o)->len; |
| 394 | 411 | case LUA_TUSERDATA: return uvalue(o)->len; |
| 395 | 412 | case LUA_TTABLE: return luaH_getn(hvalue(o)); |
| r242899 | r242900 | |
| 409 | 426 | |
| 410 | 427 | LUA_API void *lua_touserdata (lua_State *L, int idx) { |
| 411 | 428 | StkId o = index2addr(L, idx); |
| 412 | switch (ttnov(o)) { | |
| 413 | case LUA_TUSERDATA: return getudatamem(uvalue(o)); | |
| 429 | switch (ttypenv(o)) { | |
| 430 | case LUA_TUSERDATA: return (rawuvalue(o) + 1); | |
| 414 | 431 | case LUA_TLIGHTUSERDATA: return pvalue(o); |
| 415 | 432 | default: return NULL; |
| 416 | 433 | } |
| r242899 | r242900 | |
| 455 | 472 | |
| 456 | 473 | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { |
| 457 | 474 | lua_lock(L); |
| 458 | setfltvalue(L->top, n); | |
| 475 | setnvalue(L->top, n); | |
| 476 | luai_checknum(L, L->top, | |
| 477 | luaG_runerror(L, "C API - attempt to push a signaling NaN")); | |
| 459 | 478 | api_incr_top(L); |
| 460 | 479 | lua_unlock(L); |
| 461 | 480 | } |
| r242899 | r242900 | |
| 463 | 482 | |
| 464 | 483 | LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { |
| 465 | 484 | lua_lock(L); |
| 466 | set | |
| 485 | setnvalue(L->top, cast_num(n)); | |
| 467 | 486 | api_incr_top(L); |
| 468 | 487 | lua_unlock(L); |
| 469 | 488 | } |
| 470 | 489 | |
| 471 | 490 | |
| 491 | LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) { | |
| 492 | lua_Number n; | |
| 493 | lua_lock(L); | |
| 494 | n = lua_unsigned2number(u); | |
| 495 | setnvalue(L->top, n); | |
| 496 | api_incr_top(L); | |
| 497 | lua_unlock(L); | |
| 498 | } | |
| 499 | ||
| 500 | ||
| 472 | 501 | LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { |
| 473 | 502 | TString *ts; |
| 474 | 503 | lua_lock(L); |
| r242899 | r242900 | |
| 529 | 558 | setfvalue(L->top, fn); |
| 530 | 559 | } |
| 531 | 560 | else { |
| 532 | C | |
| 561 | Closure *cl; | |
| 533 | 562 | api_checknelems(L, n); |
| 534 | api_check(n <= MAXUPVAL, "upvalue index too large"); | |
| 563 | api_check(L, n <= MAXUPVAL, "upvalue index too large"); | |
| 535 | 564 | luaC_checkGC(L); |
| 536 | 565 | cl = luaF_newCclosure(L, n); |
| 537 | cl->f = fn; | |
| 566 | cl->c.f = fn; | |
| 538 | 567 | L->top -= n; |
| 539 | while (n--) { | |
| 540 | setobj2n(L, &cl->upvalue[n], L->top + n); | |
| 541 | /* does not need barrier because closure is white */ | |
| 542 | } | |
| 568 | while (n--) | |
| 569 | setobj2n(L, &cl->c.upvalue[n], L->top + n); | |
| 543 | 570 | setclCvalue(L, L->top, cl); |
| 544 | 571 | } |
| 545 | 572 | api_incr_top(L); |
| r242899 | r242900 | |
| 578 | 605 | */ |
| 579 | 606 | |
| 580 | 607 | |
| 581 | LUA_API i | |
| 608 | LUA_API void lua_getglobal (lua_State *L, const char *var) { | |
| 582 | 609 | Table *reg = hvalue(&G(L)->l_registry); |
| 583 | 610 | const TValue *gt; /* global table */ |
| 584 | 611 | lua_lock(L); |
| 585 | 612 | gt = luaH_getint(reg, LUA_RIDX_GLOBALS); |
| 586 | setsvalue2s(L, L->top++, luaS_new(L, | |
| 613 | setsvalue2s(L, L->top++, luaS_new(L, var)); | |
| 587 | 614 | luaV_gettable(L, gt, L->top - 1, L->top - 1); |
| 588 | 615 | lua_unlock(L); |
| 589 | return ttnov(L->top - 1); | |
| 590 | 616 | } |
| 591 | 617 | |
| 592 | 618 | |
| 593 | LUA_API i | |
| 619 | LUA_API void lua_gettable (lua_State *L, int idx) { | |
| 594 | 620 | StkId t; |
| 595 | 621 | lua_lock(L); |
| 596 | 622 | t = index2addr(L, idx); |
| 597 | 623 | luaV_gettable(L, t, L->top - 1, L->top - 1); |
| 598 | 624 | lua_unlock(L); |
| 599 | return ttnov(L->top - 1); | |
| 600 | 625 | } |
| 601 | 626 | |
| 602 | 627 | |
| 603 | LUA_API i | |
| 628 | LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { | |
| 604 | 629 | StkId t; |
| 605 | 630 | lua_lock(L); |
| 606 | 631 | t = index2addr(L, idx); |
| r242899 | r242900 | |
| 608 | 633 | api_incr_top(L); |
| 609 | 634 | luaV_gettable(L, t, L->top - 1, L->top - 1); |
| 610 | 635 | lua_unlock(L); |
| 611 | return ttnov(L->top - 1); | |
| 612 | 636 | } |
| 613 | 637 | |
| 614 | 638 | |
| 615 | LUA_API i | |
| 639 | LUA_API void lua_rawget (lua_State *L, int idx) { | |
| 616 | 640 | StkId t; |
| 617 | 641 | lua_lock(L); |
| 618 | 642 | t = index2addr(L, idx); |
| 619 | setivalue(L->top, n); | |
| 620 | api_incr_top(L); | |
| 621 | luaV_gettable(L, t, L->top - 1, L->top - 1); | |
| 622 | lua_unlock(L); | |
| 623 | return ttnov(L->top - 1); | |
| 624 | } | |
| 625 | ||
| 626 | ||
| 627 | LUA_API int lua_rawget (lua_State *L, int idx) { | |
| 628 | StkId t; | |
| 629 | lua_lock(L); | |
| 630 | t = index2addr(L, idx); | |
| 631 | api_check(ttistable(t), "table expected"); | |
| 643 | api_check(L, ttistable(t), "table expected"); | |
| 632 | 644 | setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); |
| 633 | 645 | lua_unlock(L); |
| 634 | return ttnov(L->top - 1); | |
| 635 | 646 | } |
| 636 | 647 | |
| 637 | 648 | |
| 638 | LUA_API i | |
| 649 | LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { | |
| 639 | 650 | StkId t; |
| 640 | 651 | lua_lock(L); |
| 641 | 652 | t = index2addr(L, idx); |
| 642 | api_check(ttistable(t), "table expected"); | |
| 653 | api_check(L, ttistable(t), "table expected"); | |
| 643 | 654 | setobj2s(L, L->top, luaH_getint(hvalue(t), n)); |
| 644 | 655 | api_incr_top(L); |
| 645 | 656 | lua_unlock(L); |
| 646 | return ttnov(L->top - 1); | |
| 647 | 657 | } |
| 648 | 658 | |
| 649 | 659 | |
| 650 | LUA_API i | |
| 660 | LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) { | |
| 651 | 661 | StkId t; |
| 652 | 662 | TValue k; |
| 653 | 663 | lua_lock(L); |
| 654 | 664 | t = index2addr(L, idx); |
| 655 | api_check(ttistable(t), "table expected"); | |
| 665 | api_check(L, ttistable(t), "table expected"); | |
| 656 | 666 | setpvalue(&k, cast(void *, p)); |
| 657 | 667 | setobj2s(L, L->top, luaH_get(hvalue(t), &k)); |
| 658 | 668 | api_incr_top(L); |
| 659 | 669 | lua_unlock(L); |
| 660 | return ttnov(L->top - 1); | |
| 661 | 670 | } |
| 662 | 671 | |
| 663 | 672 | |
| r242899 | r242900 | |
| 676 | 685 | |
| 677 | 686 | LUA_API int lua_getmetatable (lua_State *L, int objindex) { |
| 678 | 687 | const TValue *obj; |
| 679 | Table *mt; | |
| 680 | int res = 0; | |
| 688 | Table *mt = NULL; | |
| 689 | int res; | |
| 681 | 690 | lua_lock(L); |
| 682 | 691 | obj = index2addr(L, objindex); |
| 683 | switch (ttn | |
| 692 | switch (ttypenv(obj)) { | |
| 684 | 693 | case LUA_TTABLE: |
| 685 | 694 | mt = hvalue(obj)->metatable; |
| 686 | 695 | break; |
| r242899 | r242900 | |
| 688 | 697 | mt = uvalue(obj)->metatable; |
| 689 | 698 | break; |
| 690 | 699 | default: |
| 691 | mt = G(L)->mt[ttn | |
| 700 | mt = G(L)->mt[ttypenv(obj)]; | |
| 692 | 701 | break; |
| 693 | 702 | } |
| 694 | if (mt != NULL) { | |
| 703 | if (mt == NULL) | |
| 704 | res = 0; | |
| 705 | else { | |
| 695 | 706 | sethvalue(L, L->top, mt); |
| 696 | 707 | api_incr_top(L); |
| 697 | 708 | res = 1; |
| r242899 | r242900 | |
| 701 | 712 | } |
| 702 | 713 | |
| 703 | 714 | |
| 704 | LUA_API i | |
| 715 | LUA_API void lua_getuservalue (lua_State *L, int idx) { | |
| 705 | 716 | StkId o; |
| 706 | 717 | lua_lock(L); |
| 707 | 718 | o = index2addr(L, idx); |
| 708 | api_check(ttisfulluserdata(o), "full userdata expected"); | |
| 709 | getuservalue(L, uvalue(o), L->top); | |
| 719 | api_check(L, ttisuserdata(o), "userdata expected"); | |
| 720 | if (uvalue(o)->env) { | |
| 721 | sethvalue(L, L->top, uvalue(o)->env); | |
| 722 | } else | |
| 723 | setnilvalue(L->top); | |
| 710 | 724 | api_incr_top(L); |
| 711 | 725 | lua_unlock(L); |
| 712 | return ttnov(L->top - 1); | |
| 713 | 726 | } |
| 714 | 727 | |
| 715 | 728 | |
| r242899 | r242900 | |
| 718 | 731 | */ |
| 719 | 732 | |
| 720 | 733 | |
| 721 | LUA_API void lua_setglobal (lua_State *L, const char * | |
| 734 | LUA_API void lua_setglobal (lua_State *L, const char *var) { | |
| 722 | 735 | Table *reg = hvalue(&G(L)->l_registry); |
| 723 | 736 | const TValue *gt; /* global table */ |
| 724 | 737 | lua_lock(L); |
| 725 | 738 | api_checknelems(L, 1); |
| 726 | 739 | gt = luaH_getint(reg, LUA_RIDX_GLOBALS); |
| 727 | setsvalue2s(L, L->top++, luaS_new(L, | |
| 740 | setsvalue2s(L, L->top++, luaS_new(L, var)); | |
| 728 | 741 | luaV_settable(L, gt, L->top - 1, L->top - 2); |
| 729 | 742 | L->top -= 2; /* pop value and key */ |
| 730 | 743 | lua_unlock(L); |
| r242899 | r242900 | |
| 754 | 767 | } |
| 755 | 768 | |
| 756 | 769 | |
| 757 | LUA_API void lua_set | |
| 770 | LUA_API void lua_rawset (lua_State *L, int idx) { | |
| 758 | 771 | StkId t; |
| 759 | 772 | lua_lock(L); |
| 760 | api_checknelems(L, | |
| 773 | api_checknelems(L, 2); | |
| 761 | 774 | t = index2addr(L, idx); |
| 762 | setivalue(L->top++, n); | |
| 763 | luaV_settable(L, t, L->top - 1, L->top - 2); | |
| 764 | L->top -= 2; /* pop value and key */ | |
| 765 | lua_unlock(L); | |
| 766 | } | |
| 767 | ||
| 768 | ||
| 769 | LUA_API void lua_rawset (lua_State *L, int idx) { | |
| 770 | StkId o; | |
| 771 | Table *t; | |
| 772 | lua_lock(L); | |
| 773 | api_checknelems(L, 2); | |
| 774 | o = index2addr(L, idx); | |
| 775 | api_check(ttistable(o), "table expected"); | |
| 776 | t = hvalue(o); | |
| 777 | setobj2t(L, luaH_set(L, t, L->top-2), L->top-1); | |
| 778 | invalidateTMcache(t); | |
| 779 | luaC_barrierback(L, t, L->top-1); | |
| 775 | api_check(L, ttistable(t), "table expected"); | |
| 776 | setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); | |
| 777 | invalidateTMcache(hvalue(t)); | |
| 778 | luaC_barrierback(L, gcvalue(t), L->top-1); | |
| 780 | 779 | L->top -= 2; |
| 781 | 780 | lua_unlock(L); |
| 782 | 781 | } |
| 783 | 782 | |
| 784 | 783 | |
| 785 | LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { | |
| 786 | StkId o; | |
| 787 | Table *t; | |
| 784 | LUA_API void lua_rawseti (lua_State *L, int idx, int n) { | |
| 785 | StkId t; | |
| 788 | 786 | lua_lock(L); |
| 789 | 787 | api_checknelems(L, 1); |
| 790 | o = index2addr(L, idx); | |
| 791 | api_check(ttistable(o), "table expected"); | |
| 792 | t = hvalue(o); | |
| 793 | luaH_setint(L, t, n, L->top - 1); | |
| 794 | luaC_barrierback(L, t, L->top-1); | |
| 788 | t = index2addr(L, idx); | |
| 789 | api_check(L, ttistable(t), "table expected"); | |
| 790 | luaH_setint(L, hvalue(t), n, L->top - 1); | |
| 791 | luaC_barrierback(L, gcvalue(t), L->top-1); | |
| 795 | 792 | L->top--; |
| 796 | 793 | lua_unlock(L); |
| 797 | 794 | } |
| 798 | 795 | |
| 799 | 796 | |
| 800 | 797 | LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { |
| 801 | StkId o; | |
| 802 | Table *t; | |
| 798 | StkId t; | |
| 803 | 799 | TValue k; |
| 804 | 800 | lua_lock(L); |
| 805 | 801 | api_checknelems(L, 1); |
| 806 | o = index2addr(L, idx); | |
| 807 | api_check(ttistable(o), "table expected"); | |
| 808 | t = hvalue(o); | |
| 802 | t = index2addr(L, idx); | |
| 803 | api_check(L, ttistable(t), "table expected"); | |
| 809 | 804 | setpvalue(&k, cast(void *, p)); |
| 810 | setobj2t(L, luaH_set(L, t, &k), L->top - 1); | |
| 811 | luaC_barrierback(L, t, L->top - 1); | |
| 805 | setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1); | |
| 806 | luaC_barrierback(L, gcvalue(t), L->top - 1); | |
| 812 | 807 | L->top--; |
| 813 | 808 | lua_unlock(L); |
| 814 | 809 | } |
| r242899 | r242900 | |
| 823 | 818 | if (ttisnil(L->top - 1)) |
| 824 | 819 | mt = NULL; |
| 825 | 820 | else { |
| 826 | api_check(ttistable(L->top - 1), "table expected"); | |
| 821 | api_check(L, ttistable(L->top - 1), "table expected"); | |
| 827 | 822 | mt = hvalue(L->top - 1); |
| 828 | 823 | } |
| 829 | switch (ttn | |
| 824 | switch (ttypenv(obj)) { | |
| 830 | 825 | case LUA_TTABLE: { |
| 831 | 826 | hvalue(obj)->metatable = mt; |
| 832 | 827 | if (mt) { |
| 833 | luaC_objbarrier(L, gcvalue(obj), mt); | |
| 828 | luaC_objbarrierback(L, gcvalue(obj), mt); | |
| 834 | 829 | luaC_checkfinalizer(L, gcvalue(obj), mt); |
| 835 | 830 | } |
| 836 | 831 | break; |
| r242899 | r242900 | |
| 838 | 833 | case LUA_TUSERDATA: { |
| 839 | 834 | uvalue(obj)->metatable = mt; |
| 840 | 835 | if (mt) { |
| 841 | luaC_objbarrier(L, uvalue(obj), mt); | |
| 836 | luaC_objbarrier(L, rawuvalue(obj), mt); | |
| 842 | 837 | luaC_checkfinalizer(L, gcvalue(obj), mt); |
| 843 | 838 | } |
| 844 | 839 | break; |
| 845 | 840 | } |
| 846 | 841 | default: { |
| 847 | G(L)->mt[ttn | |
| 842 | G(L)->mt[ttypenv(obj)] = mt; | |
| 848 | 843 | break; |
| 849 | 844 | } |
| 850 | 845 | } |
| r242899 | r242900 | |
| 859 | 854 | lua_lock(L); |
| 860 | 855 | api_checknelems(L, 1); |
| 861 | 856 | o = index2addr(L, idx); |
| 862 | api_check(ttisfulluserdata(o), "full userdata expected"); | |
| 863 | setuservalue(L, uvalue(o), L->top - 1); | |
| 864 | luaC_barrier(L, gcvalue(o), L->top - 1); | |
| 857 | api_check(L, ttisuserdata(o), "userdata expected"); | |
| 858 | if (ttisnil(L->top - 1)) | |
| 859 | uvalue(o)->env = NULL; | |
| 860 | else { | |
| 861 | api_check(L, ttistable(L->top - 1), "table expected"); | |
| 862 | uvalue(o)->env = hvalue(L->top - 1); | |
| 863 | luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); | |
| 864 | } | |
| 865 | 865 | L->top--; |
| 866 | 866 | lua_unlock(L); |
| 867 | 867 | } |
| 868 | 868 | |
| 869 | 869 | |
| 870 | 870 | /* |
| 871 | ** | |
| 871 | ** `load' and `call' functions (run Lua code) | |
| 872 | 872 | */ |
| 873 | 873 | |
| 874 | 874 | |
| 875 | 875 | #define checkresults(L,na,nr) \ |
| 876 | api_check((nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ | |
| 876 | api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ | |
| 877 | 877 | "results from function overflow current stack size") |
| 878 | 878 | |
| 879 | 879 | |
| 880 | LUA_API void lua_callk (lua_State *L, int nargs, int nresults, | |
| 881 | lua_KContext ctx, lua_KFunction k) { | |
| 880 | LUA_API int lua_getctx (lua_State *L, int *ctx) { | |
| 881 | if (L->ci->callstatus & CIST_YIELDED) { | |
| 882 | if (ctx) *ctx = L->ci->u.c.ctx; | |
| 883 | return L->ci->u.c.status; | |
| 884 | } | |
| 885 | else return LUA_OK; | |
| 886 | } | |
| 887 | ||
| 888 | ||
| 889 | LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx, | |
| 890 | lua_CFunction k) { | |
| 882 | 891 | StkId func; |
| 883 | 892 | lua_lock(L); |
| 884 | api_check(k == NULL || !isLua(L->ci), | |
| 893 | api_check(L, k == NULL || !isLua(L->ci), | |
| 885 | 894 | "cannot use continuations inside hooks"); |
| 886 | 895 | api_checknelems(L, nargs+1); |
| 887 | api_check(L->status == LUA_OK, "cannot do calls on non-normal thread"); | |
| 896 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); | |
| 888 | 897 | checkresults(L, nargs, nresults); |
| 889 | 898 | func = L->top - (nargs+1); |
| 890 | 899 | if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ |
| r242899 | r242900 | |
| 903 | 912 | /* |
| 904 | 913 | ** Execute a protected call. |
| 905 | 914 | */ |
| 906 | struct CallS { /* data to | |
| 915 | struct CallS { /* data to `f_call' */ | |
| 907 | 916 | StkId func; |
| 908 | 917 | int nresults; |
| 909 | 918 | }; |
| r242899 | r242900 | |
| 917 | 926 | |
| 918 | 927 | |
| 919 | 928 | LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, |
| 920 | | |
| 929 | int ctx, lua_CFunction k) { | |
| 921 | 930 | struct CallS c; |
| 922 | 931 | int status; |
| 923 | 932 | ptrdiff_t func; |
| 924 | 933 | lua_lock(L); |
| 925 | api_check(k == NULL || !isLua(L->ci), | |
| 934 | api_check(L, k == NULL || !isLua(L->ci), | |
| 926 | 935 | "cannot use continuations inside hooks"); |
| 927 | 936 | api_checknelems(L, nargs+1); |
| 928 | api_check(L->status == LUA_OK, "cannot do calls on non-normal thread"); | |
| 937 | api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); | |
| 929 | 938 | checkresults(L, nargs, nresults); |
| 930 | 939 | if (errfunc == 0) |
| 931 | 940 | func = 0; |
| 932 | 941 | else { |
| 933 | 942 | StkId o = index2addr(L, errfunc); |
| 934 | api_checkstackindex(errfunc, o); | |
| 943 | api_checkstackindex(L, errfunc, o); | |
| 935 | 944 | func = savestack(L, o); |
| 936 | 945 | } |
| 937 | 946 | c.func = L->top - (nargs+1); /* function to be called */ |
| r242899 | r242900 | |
| 945 | 954 | ci->u.c.ctx = ctx; /* save context */ |
| 946 | 955 | /* save information for error recovery */ |
| 947 | 956 | ci->extra = savestack(L, c.func); |
| 957 | ci->u.c.old_allowhook = L->allowhook; | |
| 948 | 958 | ci->u.c.old_errfunc = L->errfunc; |
| 949 | 959 | L->errfunc = func; |
| 950 | setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ | |
| 951 | ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ | |
| 960 | /* mark that function may do error recovery */ | |
| 961 | ci->callstatus |= CIST_YPCALL; | |
| 952 | 962 | luaD_call(L, c.func, nresults, 1); /* do the call */ |
| 953 | 963 | ci->callstatus &= ~CIST_YPCALL; |
| 954 | 964 | L->errfunc = ci->u.c.old_errfunc; |
| r242899 | r242900 | |
| 970 | 980 | status = luaD_protectedparser(L, &z, chunkname, mode); |
| 971 | 981 | if (status == LUA_OK) { /* no errors? */ |
| 972 | 982 | LClosure *f = clLvalue(L->top - 1); /* get newly created function */ |
| 973 | if (f->nupvalues | |
| 983 | if (f->nupvalues == 1) { /* does it have one upvalue? */ | |
| 974 | 984 | /* get global table from registry */ |
| 975 | 985 | Table *reg = hvalue(&G(L)->l_registry); |
| 976 | 986 | const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); |
| 977 | 987 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ |
| 978 | 988 | setobj(L, f->upvals[0]->v, gt); |
| 979 | luaC_ | |
| 989 | luaC_barrier(L, f->upvals[0], gt); | |
| 980 | 990 | } |
| 981 | 991 | } |
| 982 | 992 | lua_unlock(L); |
| r242899 | r242900 | |
| 984 | 994 | } |
| 985 | 995 | |
| 986 | 996 | |
| 987 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data | |
| 997 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { | |
| 988 | 998 | int status; |
| 989 | 999 | TValue *o; |
| 990 | 1000 | lua_lock(L); |
| 991 | 1001 | api_checknelems(L, 1); |
| 992 | 1002 | o = L->top - 1; |
| 993 | 1003 | if (isLfunction(o)) |
| 994 | status = luaU_dump(L, getproto(o), writer, data, | |
| 1004 | status = luaU_dump(L, getproto(o), writer, data, 0); | |
| 995 | 1005 | else |
| 996 | 1006 | status = 1; |
| 997 | 1007 | lua_unlock(L); |
| r242899 | r242900 | |
| 1037 | 1047 | break; |
| 1038 | 1048 | } |
| 1039 | 1049 | case LUA_GCSTEP: { |
| 1040 | l_mem debt = 1; /* =1 to signal that it did an actual step */ | |
| 1041 | int oldrunning = g->gcrunning; | |
| 1042 | g->gcrunning = 1; /* allow GC to run */ | |
| 1043 | if (data == 0) { | |
| 1044 | luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */ | |
| 1045 | luaC_step(L); | |
| 1050 | if (g->gckind == KGC_GEN) { /* generational mode? */ | |
| 1051 | res = (g->GCestimate == 0); /* true if it will do major collection */ | |
| 1052 | luaC_forcestep(L); /* do a single step */ | |
| 1046 | 1053 | } |
| 1047 | else { /* add 'data' to total debt */ | |
| 1048 | debt = cast(l_mem, data) * 1024 + g->GCdebt; | |
| 1049 | luaE_setdebt(g, debt); | |
| 1050 | luaC_checkGC(L); | |
| 1054 | else { | |
| 1055 | lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE; | |
| 1056 | if (g->gcrunning) | |
| 1057 | debt += g->GCdebt; /* include current debt */ | |
| 1058 | luaE_setdebt(g, debt); | |
| 1059 | luaC_forcestep(L); | |
| 1060 | if (g->gcstate == GCSpause) /* end of cycle? */ | |
| 1061 | res = 1; /* signal it */ | |
| 1051 | 1062 | } |
| 1052 | g->gcrunning = oldrunning; /* restore previous state */ | |
| 1053 | if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ | |
| 1054 | res = 1; /* signal it */ | |
| 1055 | 1063 | break; |
| 1056 | 1064 | } |
| 1057 | 1065 | case LUA_GCSETPAUSE: { |
| r242899 | r242900 | |
| 1059 | 1067 | g->gcpause = data; |
| 1060 | 1068 | break; |
| 1061 | 1069 | } |
| 1070 | case LUA_GCSETMAJORINC: { | |
| 1071 | res = g->gcmajorinc; | |
| 1072 | g->gcmajorinc = data; | |
| 1073 | break; | |
| 1074 | } | |
| 1062 | 1075 | case LUA_GCSETSTEPMUL: { |
| 1063 | 1076 | res = g->gcstepmul; |
| 1064 | if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */ | |
| 1065 | 1077 | g->gcstepmul = data; |
| 1066 | 1078 | break; |
| 1067 | 1079 | } |
| r242899 | r242900 | |
| 1069 | 1081 | res = g->gcrunning; |
| 1070 | 1082 | break; |
| 1071 | 1083 | } |
| 1084 | case LUA_GCGEN: { /* change collector to generational mode */ | |
| 1085 | luaC_changemode(L, KGC_GEN); | |
| 1086 | break; | |
| 1087 | } | |
| 1088 | case LUA_GCINC: { /* change collector to incremental mode */ | |
| 1089 | luaC_changemode(L, KGC_NORMAL); | |
| 1090 | break; | |
| 1091 | } | |
| 1072 | 1092 | default: res = -1; /* invalid option */ |
| 1073 | 1093 | } |
| 1074 | 1094 | lua_unlock(L); |
| r242899 | r242900 | |
| 1096 | 1116 | int more; |
| 1097 | 1117 | lua_lock(L); |
| 1098 | 1118 | t = index2addr(L, idx); |
| 1099 | api_check(ttistable(t), "table expected"); | |
| 1119 | api_check(L, ttistable(t), "table expected"); | |
| 1100 | 1120 | more = luaH_next(L, hvalue(t), L->top - 1); |
| 1101 | 1121 | if (more) { |
| 1102 | 1122 | api_incr_top(L); |
| r242899 | r242900 | |
| 1156 | 1176 | Udata *u; |
| 1157 | 1177 | lua_lock(L); |
| 1158 | 1178 | luaC_checkGC(L); |
| 1159 | u = luaS_newudata(L, size); | |
| 1179 | u = luaS_newudata(L, size, NULL); | |
| 1160 | 1180 | setuvalue(L, L->top, u); |
| 1161 | 1181 | api_incr_top(L); |
| 1162 | 1182 | lua_unlock(L); |
| 1163 | return | |
| 1183 | return u + 1; | |
| 1164 | 1184 | } |
| 1165 | 1185 | |
| 1166 | 1186 | |
| 1167 | 1187 | |
| 1168 | 1188 | static const char *aux_upvalue (StkId fi, int n, TValue **val, |
| 1169 | C | |
| 1189 | GCObject **owner) { | |
| 1170 | 1190 | switch (ttype(fi)) { |
| 1171 | 1191 | case LUA_TCCL: { /* C closure */ |
| 1172 | 1192 | CClosure *f = clCvalue(fi); |
| 1173 | 1193 | if (!(1 <= n && n <= f->nupvalues)) return NULL; |
| 1174 | 1194 | *val = &f->upvalue[n-1]; |
| 1175 | if (owner) *owner = f; | |
| 1195 | if (owner) *owner = obj2gco(f); | |
| 1176 | 1196 | return ""; |
| 1177 | 1197 | } |
| 1178 | 1198 | case LUA_TLCL: { /* Lua closure */ |
| r242899 | r242900 | |
| 1181 | 1201 | Proto *p = f->p; |
| 1182 | 1202 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; |
| 1183 | 1203 | *val = f->upvals[n-1]->v; |
| 1184 | if ( | |
| 1204 | if (owner) *owner = obj2gco(f->upvals[n - 1]); | |
| 1185 | 1205 | name = p->upvalues[n-1].name; |
| 1186 | return (name == NULL) ? " | |
| 1206 | return (name == NULL) ? "" : getstr(name); | |
| 1187 | 1207 | } |
| 1188 | 1208 | default: return NULL; /* not a closure */ |
| 1189 | 1209 | } |
| r242899 | r242900 | |
| 1194 | 1214 | const char *name; |
| 1195 | 1215 | TValue *val = NULL; /* to avoid warnings */ |
| 1196 | 1216 | lua_lock(L); |
| 1197 | name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL | |
| 1217 | name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); | |
| 1198 | 1218 | if (name) { |
| 1199 | 1219 | setobj2s(L, L->top, val); |
| 1200 | 1220 | api_incr_top(L); |
| r242899 | r242900 | |
| 1207 | 1227 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { |
| 1208 | 1228 | const char *name; |
| 1209 | 1229 | TValue *val = NULL; /* to avoid warnings */ |
| 1210 | CClosure *owner = NULL; | |
| 1211 | UpVal *uv = NULL; | |
| 1230 | GCObject *owner = NULL; /* to avoid warnings */ | |
| 1212 | 1231 | StkId fi; |
| 1213 | 1232 | lua_lock(L); |
| 1214 | 1233 | fi = index2addr(L, funcindex); |
| 1215 | 1234 | api_checknelems(L, 1); |
| 1216 | name = aux_upvalue(fi, n, &val, &owner | |
| 1235 | name = aux_upvalue(fi, n, &val, &owner); | |
| 1217 | 1236 | if (name) { |
| 1218 | 1237 | L->top--; |
| 1219 | 1238 | setobj(L, val, L->top); |
| 1220 | if (owner) { luaC_barrier(L, owner, L->top); } | |
| 1221 | else if (uv) { luaC_upvalbarrier(L, uv); } | |
| 1239 | luaC_barrier(L, owner, L->top); | |
| 1222 | 1240 | } |
| 1223 | 1241 | lua_unlock(L); |
| 1224 | 1242 | return name; |
| r242899 | r242900 | |
| 1228 | 1246 | static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { |
| 1229 | 1247 | LClosure *f; |
| 1230 | 1248 | StkId fi = index2addr(L, fidx); |
| 1231 | api_check(ttisLclosure(fi), "Lua function expected"); | |
| 1249 | api_check(L, ttisLclosure(fi), "Lua function expected"); | |
| 1232 | 1250 | f = clLvalue(fi); |
| 1233 | api_check((1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); | |
| 1251 | api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); | |
| 1234 | 1252 | if (pf) *pf = f; |
| 1235 | 1253 | return &f->upvals[n - 1]; /* get its upvalue pointer */ |
| 1236 | 1254 | } |
| r242899 | r242900 | |
| 1244 | 1262 | } |
| 1245 | 1263 | case LUA_TCCL: { /* C closure */ |
| 1246 | 1264 | CClosure *f = clCvalue(fi); |
| 1247 | api_check(1 <= n && n <= f->nupvalues, "invalid upvalue index"); | |
| 1265 | api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); | |
| 1248 | 1266 | return &f->upvalue[n - 1]; |
| 1249 | 1267 | } |
| 1250 | 1268 | default: { |
| 1251 | api_check(0, "closure expected"); | |
| 1269 | api_check(L, 0, "closure expected"); | |
| 1252 | 1270 | return NULL; |
| 1253 | 1271 | } |
| 1254 | 1272 | } |
| r242899 | r242900 | |
| 1260 | 1278 | LClosure *f1; |
| 1261 | 1279 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); |
| 1262 | 1280 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); |
| 1263 | luaC_upvdeccount(L, *up1); | |
| 1264 | 1281 | *up1 = *up2; |
| 1265 | (*up1)->refcount++; | |
| 1266 | if (upisopen(*up1)) (*up1)->u.open.touched = 1; | |
| 1267 | luaC_upvalbarrier(L, *up1); | |
| 1282 | luaC_objbarrier(L, f1, *up2); | |
| 1268 | 1283 | } |
| 1269 | 1284 | |
| 1270 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lapi.h,v 2. | |
| 2 | ** $Id: lapi.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions from Lua API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 11 | 11 | #include "llimits.h" |
| 12 | 12 | #include "lstate.h" |
| 13 | 13 | |
| 14 | #define api_incr_top(L) {L->top++; api_check(L->top <= L->ci->top, \ | |
| 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ | |
| 15 | 15 | "stack overflow");} |
| 16 | 16 | |
| 17 | 17 | #define adjustresults(L,nres) \ |
| 18 | 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } |
| 19 | 19 | |
| 20 | #define api_checknelems(L,n) api_check((n) < (L->top - L->ci->func), \ | |
| 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ | |
| 21 | 21 | "not enough elements in the stack") |
| 22 | 22 | |
| 23 | 23 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.2 | |
| 2 | ** $Id: lauxlib.c,v 1.248.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lauxlib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <errno.h> |
| 14 | 9 | #include <stdarg.h> |
| 15 | 10 | #include <stdio.h> |
| r242899 | r242900 | |
| 21 | 16 | ** Any function declared here could be written as an application function. |
| 22 | 17 | */ |
| 23 | 18 | |
| 19 | #define lauxlib_c | |
| 20 | #define LUA_LIB | |
| 21 | ||
| 24 | 22 | #include "lua.h" |
| 25 | 23 | |
| 26 | 24 | #include "lauxlib.h" |
| r242899 | r242900 | |
| 66 | 64 | } |
| 67 | 65 | |
| 68 | 66 | |
| 69 | /* | |
| 70 | ** Search for a name for a function in all loaded modules | |
| 71 | ** (registry._LOADED). | |
| 72 | */ | |
| 73 | 67 | static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { |
| 74 | 68 | int top = lua_gettop(L); |
| 75 | 69 | lua_getinfo(L, "f", ar); /* push function */ |
| 76 | lua_g | |
| 70 | lua_pushglobaltable(L); | |
| 77 | 71 | if (findfield(L, top + 1, 2)) { |
| 78 | const char *name = lua_tostring(L, -1); | |
| 79 | if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */ | |
| 80 | lua_pushstring(L, name + 3); /* push name without prefix */ | |
| 81 | lua_remove(L, -2); /* remove original name */ | |
| 82 | } | |
| 83 | 72 | lua_copy(L, -1, top + 1); /* move name to proper place */ |
| 84 | 73 | lua_pop(L, 2); /* remove pushed values */ |
| 85 | 74 | return 1; |
| r242899 | r242900 | |
| 92 | 81 | |
| 93 | 82 | |
| 94 | 83 | static void pushfuncname (lua_State *L, lua_Debug *ar) { |
| 95 | if (pushglobalfuncname(L, ar)) { /* try first a global name */ | |
| 96 | lua_pushfstring(L, "function '%s'", lua_tostring(L, -1)); | |
| 97 | lua_remove(L, -2); /* remove name */ | |
| 98 | } | |
| 99 | else if (*ar->namewhat != '\0') /* is there a name from code? */ | |
| 100 | lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */ | |
| 84 | if (*ar->namewhat != '\0') /* is there a name? */ | |
| 85 | lua_pushfstring(L, "function " LUA_QS, ar->name); | |
| 101 | 86 | else if (*ar->what == 'm') /* main? */ |
| 102 | 87 | lua_pushliteral(L, "main chunk"); |
| 103 | else if (*ar->what != 'C') /* for Lua functions, use <file:line> */ | |
| 88 | else if (*ar->what == 'C') { | |
| 89 | if (pushglobalfuncname(L, ar)) { | |
| 90 | lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); | |
| 91 | lua_remove(L, -2); /* remove name */ | |
| 92 | } | |
| 93 | else | |
| 94 | lua_pushliteral(L, "?"); | |
| 95 | } | |
| 96 | else | |
| 104 | 97 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); |
| 105 | else /* nothing left... */ | |
| 106 | lua_pushliteral(L, "?"); | |
| 107 | 98 | } |
| 108 | 99 | |
| 109 | 100 | |
| r242899 | r242900 | |
| 159 | 150 | ** ======================================================= |
| 160 | 151 | */ |
| 161 | 152 | |
| 162 | LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { | |
| 153 | LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { | |
| 163 | 154 | lua_Debug ar; |
| 164 | 155 | if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ |
| 165 | return luaL_error(L, "bad argument #%d (%s)", arg, extramsg); | |
| 156 | return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); | |
| 166 | 157 | lua_getinfo(L, "n", &ar); |
| 167 | 158 | if (strcmp(ar.namewhat, "method") == 0) { |
| 168 | arg--; /* do not count 'self' */ | |
| 169 | if (arg == 0) /* error is in the self argument itself? */ | |
| 170 | return luaL_error(L, "calling '%s' on bad self (%s)", | |
| 159 | narg--; /* do not count `self' */ | |
| 160 | if (narg == 0) /* error is in the self argument itself? */ | |
| 161 | return luaL_error(L, "calling " LUA_QS " on bad self (%s)", | |
| 171 | 162 | ar.name, extramsg); |
| 172 | 163 | } |
| 173 | 164 | if (ar.name == NULL) |
| 174 | 165 | ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; |
| 175 | return luaL_error(L, "bad argument #%d to '%s' (%s)", | |
| 176 | arg, ar.name, extramsg); | |
| 166 | return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", | |
| 167 | narg, ar.name, extramsg); | |
| 177 | 168 | } |
| 178 | 169 | |
| 179 | 170 | |
| 180 | static int typeerror (lua_State *L, int arg, const char *tname) { | |
| 181 | const char *msg; | |
| 182 | const char *typearg; /* name for the type of the actual argument */ | |
| 183 | if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) | |
| 184 | typearg = lua_tostring(L, -1); /* use the given type name */ | |
| 185 | else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA) | |
| 186 | typearg = "light userdata"; /* special name for messages */ | |
| 187 | else | |
| 188 | typearg = luaL_typename(L, arg); /* standard name */ | |
| 189 | msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg); | |
| 190 | return luaL_argerror(L, arg, msg); | |
| 171 | static int typeerror (lua_State *L, int narg, const char *tname) { | |
| 172 | const char *msg = lua_pushfstring(L, "%s expected, got %s", | |
| 173 | tname, luaL_typename(L, narg)); | |
| 174 | return luaL_argerror(L, narg, msg); | |
| 191 | 175 | } |
| 192 | 176 | |
| 193 | 177 | |
| 194 | static void tag_error (lua_State *L, int arg, int tag) { | |
| 195 | typeerror(L, arg, lua_typename(L, tag)); | |
| 178 | static void tag_error (lua_State *L, int narg, int tag) { | |
| 179 | typeerror(L, narg, lua_typename(L, tag)); | |
| 196 | 180 | } |
| 197 | 181 | |
| 198 | 182 | |
| r242899 | r242900 | |
| 238 | 222 | } |
| 239 | 223 | |
| 240 | 224 | |
| 241 | #if !defined( | |
| 225 | #if !defined(inspectstat) /* { */ | |
| 242 | 226 | |
| 243 | 227 | #if defined(LUA_USE_POSIX) |
| 244 | 228 | |
| r242899 | r242900 | |
| 247 | 231 | /* |
| 248 | 232 | ** use appropriate macros to interpret 'pclose' return status |
| 249 | 233 | */ |
| 250 | #define | |
| 234 | #define inspectstat(stat,what) \ | |
| 251 | 235 | if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ |
| 252 | 236 | else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } |
| 253 | 237 | |
| 254 | 238 | #else |
| 255 | 239 | |
| 256 | #define | |
| 240 | #define inspectstat(stat,what) /* no op */ | |
| 257 | 241 | |
| 258 | 242 | #endif |
| 259 | 243 | |
| r242899 | r242900 | |
| 265 | 249 | if (stat == -1) /* error? */ |
| 266 | 250 | return luaL_fileresult(L, 0, NULL); |
| 267 | 251 | else { |
| 268 | | |
| 252 | inspectstat(stat, what); /* interpret result */ | |
| 269 | 253 | if (*what == 'e' && stat == 0) /* successful termination? */ |
| 270 | 254 | lua_pushboolean(L, 1); |
| 271 | 255 | else |
| r242899 | r242900 | |
| 286 | 270 | */ |
| 287 | 271 | |
| 288 | 272 | LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { |
| 289 | if (luaL_getmetatable(L, tname)) /* name already in use? */ | |
| 273 | luaL_getmetatable(L, tname); /* try to get metatable */ | |
| 274 | if (!lua_isnil(L, -1)) /* name already in use? */ | |
| 290 | 275 | return 0; /* leave previous value on top, but return 0 */ |
| 291 | 276 | lua_pop(L, 1); |
| 292 | 277 | lua_newtable(L); /* create metatable */ |
| 293 | lua_pushstring(L, tname); | |
| 294 | lua_setfield(L, -2, "__name"); /* metatable.__name = tname */ | |
| 295 | 278 | lua_pushvalue(L, -1); |
| 296 | 279 | lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ |
| 297 | 280 | return 1; |
| r242899 | r242900 | |
| 334 | 317 | ** ======================================================= |
| 335 | 318 | */ |
| 336 | 319 | |
| 337 | LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def, | |
| 320 | LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, | |
| 338 | 321 | const char *const lst[]) { |
| 339 | const char *name = (def) ? luaL_optstring(L, arg, def) : | |
| 340 | luaL_checkstring(L, arg); | |
| 322 | const char *name = (def) ? luaL_optstring(L, narg, def) : | |
| 323 | luaL_checkstring(L, narg); | |
| 341 | 324 | int i; |
| 342 | 325 | for (i=0; lst[i]; i++) |
| 343 | 326 | if (strcmp(lst[i], name) == 0) |
| 344 | 327 | return i; |
| 345 | return luaL_argerror(L, arg, | |
| 346 | lua_pushfstring(L, "invalid option '%s'", name)); | |
| 328 | return luaL_argerror(L, narg, | |
| 329 | lua_pushfstring(L, "invalid option " LUA_QS, name)); | |
| 347 | 330 | } |
| 348 | 331 | |
| 349 | 332 | |
| r242899 | r242900 | |
| 359 | 342 | } |
| 360 | 343 | |
| 361 | 344 | |
| 362 | LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) { | |
| 363 | if (lua_type(L, arg) != t) | |
| 364 | tag_error(L, arg, t); | |
| 345 | LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { | |
| 346 | if (lua_type(L, narg) != t) | |
| 347 | tag_error(L, narg, t); | |
| 365 | 348 | } |
| 366 | 349 | |
| 367 | 350 | |
| 368 | LUALIB_API void luaL_checkany (lua_State *L, int arg) { | |
| 369 | if (lua_type(L, arg) == LUA_TNONE) | |
| 370 | luaL_argerror(L, arg, "value expected"); | |
| 351 | LUALIB_API void luaL_checkany (lua_State *L, int narg) { | |
| 352 | if (lua_type(L, narg) == LUA_TNONE) | |
| 353 | luaL_argerror(L, narg, "value expected"); | |
| 371 | 354 | } |
| 372 | 355 | |
| 373 | 356 | |
| 374 | LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) { | |
| 375 | const char *s = lua_tolstring(L, arg, len); | |
| 376 | if (!s) tag_error(L, arg, LUA_TSTRING); | |
| 357 | LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { | |
| 358 | const char *s = lua_tolstring(L, narg, len); | |
| 359 | if (!s) tag_error(L, narg, LUA_TSTRING); | |
| 377 | 360 | return s; |
| 378 | 361 | } |
| 379 | 362 | |
| 380 | 363 | |
| 381 | LUALIB_API const char *luaL_optlstring (lua_State *L, int arg, | |
| 364 | LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, | |
| 382 | 365 | const char *def, size_t *len) { |
| 383 | if (lua_isnoneornil(L, arg)) { | |
| 366 | if (lua_isnoneornil(L, narg)) { | |
| 384 | 367 | if (len) |
| 385 | 368 | *len = (def ? strlen(def) : 0); |
| 386 | 369 | return def; |
| 387 | 370 | } |
| 388 | else return luaL_checklstring(L, arg, len); | |
| 371 | else return luaL_checklstring(L, narg, len); | |
| 389 | 372 | } |
| 390 | 373 | |
| 391 | 374 | |
| 392 | LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) { | |
| 375 | LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { | |
| 393 | 376 | int isnum; |
| 394 | lua_Number d = lua_tonumberx(L, arg, &isnum); | |
| 377 | lua_Number d = lua_tonumberx(L, narg, &isnum); | |
| 395 | 378 | if (!isnum) |
| 396 | tag_error(L, arg, LUA_TNUMBER); | |
| 379 | tag_error(L, narg, LUA_TNUMBER); | |
| 397 | 380 | return d; |
| 398 | 381 | } |
| 399 | 382 | |
| 400 | 383 | |
| 401 | LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) { | |
| 402 | return luaL_opt(L, luaL_checknumber, arg, def); | |
| 384 | LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { | |
| 385 | return luaL_opt(L, luaL_checknumber, narg, def); | |
| 403 | 386 | } |
| 404 | 387 | |
| 405 | 388 | |
| 406 | static void interror (lua_State *L, int arg) { | |
| 407 | if (lua_isnumber(L, arg)) | |
| 408 | luaL_argerror(L, arg, "number has no integer representation"); | |
| 409 | else | |
| 410 | tag_error(L, arg, LUA_TNUMBER); | |
| 389 | LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { | |
| 390 | int isnum; | |
| 391 | lua_Integer d = lua_tointegerx(L, narg, &isnum); | |
| 392 | if (!isnum) | |
| 393 | tag_error(L, narg, LUA_TNUMBER); | |
| 394 | return d; | |
| 411 | 395 | } |
| 412 | 396 | |
| 413 | 397 | |
| 414 | LUALIB_API lua_ | |
| 398 | LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) { | |
| 415 | 399 | int isnum; |
| 416 | lua_Integer d = lua_tointegerx(L, arg, &isnum); | |
| 417 | if (!isnum) { | |
| 418 | interror(L, arg); | |
| 419 | } | |
| 400 | lua_Unsigned d = lua_tounsignedx(L, narg, &isnum); | |
| 401 | if (!isnum) | |
| 402 | tag_error(L, narg, LUA_TNUMBER); | |
| 420 | 403 | return d; |
| 421 | 404 | } |
| 422 | 405 | |
| 423 | 406 | |
| 424 | LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg, | |
| 407 | LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, | |
| 425 | 408 | lua_Integer def) { |
| 426 | return luaL_opt(L, luaL_checkinteger, arg, def); | |
| 409 | return luaL_opt(L, luaL_checkinteger, narg, def); | |
| 427 | 410 | } |
| 428 | 411 | |
| 412 | ||
| 413 | LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg, | |
| 414 | lua_Unsigned def) { | |
| 415 | return luaL_opt(L, luaL_checkunsigned, narg, def); | |
| 416 | } | |
| 417 | ||
| 429 | 418 | /* }====================================================== */ |
| 430 | 419 | |
| 431 | 420 | |
| r242899 | r242900 | |
| 534 | 523 | int ref; |
| 535 | 524 | if (lua_isnil(L, -1)) { |
| 536 | 525 | lua_pop(L, 1); /* remove from stack */ |
| 537 | return LUA_REFNIL; /* | |
| 526 | return LUA_REFNIL; /* `nil' has a unique fixed reference */ | |
| 538 | 527 | } |
| 539 | 528 | t = lua_absindex(L, t); |
| 540 | 529 | lua_rawgeti(L, t, freelist); /* get first free element */ |
| r242899 | r242900 | |
| 573 | 562 | typedef struct LoadF { |
| 574 | 563 | int n; /* number of pre-read characters */ |
| 575 | 564 | FILE *f; /* file being read */ |
| 576 | char buff[BUFSIZ]; /* area for reading file */ | |
| 565 | char buff[LUAL_BUFFERSIZE]; /* area for reading file */ | |
| 577 | 566 | } LoadF; |
| 578 | 567 | |
| 579 | 568 | |
| r242899 | r242900 | |
| 666 | 655 | readstatus = ferror(lf.f); |
| 667 | 656 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ |
| 668 | 657 | if (readstatus) { |
| 669 | lua_settop(L, fnameindex); /* ignore results from | |
| 658 | lua_settop(L, fnameindex); /* ignore results from `lua_load' */ | |
| 670 | 659 | return errfile(L, "read", fnameindex); |
| 671 | 660 | } |
| 672 | 661 | lua_remove(L, fnameindex); |
| r242899 | r242900 | |
| 709 | 698 | |
| 710 | 699 | LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { |
| 711 | 700 | if (!lua_getmetatable(L, obj)) /* no metatable? */ |
| 712 | return LUA_TNIL; | |
| 701 | return 0; | |
| 702 | lua_pushstring(L, event); | |
| 703 | lua_rawget(L, -2); | |
| 704 | if (lua_isnil(L, -1)) { | |
| 705 | lua_pop(L, 2); /* remove metatable and metafield */ | |
| 706 | return 0; | |
| 707 | } | |
| 713 | 708 | else { |
| 714 | int tt; | |
| 715 | lua_pushstring(L, event); | |
| 716 | tt = lua_rawget(L, -2); | |
| 717 | if (tt == LUA_TNIL) /* is metafield nil? */ | |
| 718 | lua_pop(L, 2); /* remove metatable and metafield */ | |
| 719 | else | |
| 720 | lua_remove(L, -2); /* remove only metatable */ | |
| 721 | return tt; /* return metafield type */ | |
| 709 | lua_remove(L, -2); /* remove only metatable */ | |
| 710 | return 1; | |
| 722 | 711 | } |
| 723 | 712 | } |
| 724 | 713 | |
| 725 | 714 | |
| 726 | 715 | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { |
| 727 | 716 | obj = lua_absindex(L, obj); |
| 728 | if (luaL_getmetafield(L, obj, event) | |
| 717 | if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ | |
| 729 | 718 | return 0; |
| 730 | 719 | lua_pushvalue(L, obj); |
| 731 | 720 | lua_call(L, 1, 1); |
| r242899 | r242900 | |
| 733 | 722 | } |
| 734 | 723 | |
| 735 | 724 | |
| 736 | LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { | |
| 737 | lua_Integer l; | |
| 725 | LUALIB_API int luaL_len (lua_State *L, int idx) { | |
| 726 | int l; | |
| 738 | 727 | int isnum; |
| 739 | 728 | lua_len(L, idx); |
| 740 | l = lua_tointegerx(L, -1, &isnum); | |
| 729 | l = (int)lua_tointegerx(L, -1, &isnum); | |
| 741 | 730 | if (!isnum) |
| 742 | luaL_error(L, "object length is not a | |
| 731 | luaL_error(L, "object length is not a number"); | |
| 743 | 732 | lua_pop(L, 1); /* remove object */ |
| 744 | 733 | return l; |
| 745 | 734 | } |
| r242899 | r242900 | |
| 748 | 737 | LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { |
| 749 | 738 | if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ |
| 750 | 739 | switch (lua_type(L, idx)) { |
| 751 | case LUA_TNUMBER: { | |
| 752 | if (lua_isinteger(L, idx)) | |
| 753 | lua_pushfstring(L, "%I", lua_tointeger(L, idx)); | |
| 754 | else | |
| 755 | lua_pushfstring(L, "%f", lua_tonumber(L, idx)); | |
| 756 | break; | |
| 757 | } | |
| 740 | case LUA_TNUMBER: | |
| 758 | 741 | case LUA_TSTRING: |
| 759 | 742 | lua_pushvalue(L, idx); |
| 760 | 743 | break; |
| r242899 | r242900 | |
| 789 | 772 | e = strchr(fname, '.'); |
| 790 | 773 | if (e == NULL) e = fname + strlen(fname); |
| 791 | 774 | lua_pushlstring(L, fname, e - fname); |
| 792 | if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */ | |
| 775 | lua_rawget(L, -2); | |
| 776 | if (lua_isnil(L, -1)) { /* no such field? */ | |
| 793 | 777 | lua_pop(L, 1); /* remove this nil */ |
| 794 | 778 | lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ |
| 795 | 779 | lua_pushlstring(L, fname, e - fname); |
| r242899 | r242900 | |
| 826 | 810 | LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, |
| 827 | 811 | int sizehint) { |
| 828 | 812 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ |
| 829 | if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no _LOADED[modname]? */ | |
| 813 | lua_getfield(L, -1, modname); /* get _LOADED[modname] */ | |
| 814 | if (!lua_istable(L, -1)) { /* not found? */ | |
| 830 | 815 | lua_pop(L, 1); /* remove previous result */ |
| 831 | 816 | /* try global variable (and create one if it does not exist) */ |
| 832 | 817 | lua_pushglobaltable(L); |
| 833 | 818 | if (luaL_findtable(L, 0, modname, sizehint) != NULL) |
| 834 | luaL_error(L, "name conflict for module | |
| 819 | luaL_error(L, "name conflict for module " LUA_QS, modname); | |
| 835 | 820 | lua_pushvalue(L, -1); |
| 836 | 821 | lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ |
| 837 | 822 | } |
| r242899 | r242900 | |
| 861 | 846 | ** Returns with only the table at the stack. |
| 862 | 847 | */ |
| 863 | 848 | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { |
| 849 | luaL_checkversion(L); | |
| 864 | 850 | luaL_checkstack(L, nup, "too many upvalues"); |
| 865 | 851 | for (; l->name != NULL; l++) { /* fill the table with given functions */ |
| 866 | 852 | int i; |
| r242899 | r242900 | |
| 878 | 864 | ** into the stack |
| 879 | 865 | */ |
| 880 | 866 | LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { |
| 881 | if (lua_getfield(L, idx, fname) == LUA_TTABLE) | |
| 882 | return 1; /* table already there */ | |
| 867 | lua_getfield(L, idx, fname); | |
| 868 | if (lua_istable(L, -1)) return 1; /* table already there */ | |
| 883 | 869 | else { |
| 884 | 870 | lua_pop(L, 1); /* remove previous result */ |
| 885 | 871 | idx = lua_absindex(L, idx); |
| r242899 | r242900 | |
| 892 | 878 | |
| 893 | 879 | |
| 894 | 880 | /* |
| 895 | ** Stripped-down 'require': After checking "loaded" table, calls 'openf' | |
| 896 | ** to open a module, registers the result in 'package.loaded' table and, | |
| 897 | ** if 'glb' is true, also registers the result in the global table. | |
| 881 | ** stripped-down 'require'. Calls 'openf' to open a module, | |
| 882 | ** registers the result in 'package.loaded' table and, if 'glb' | |
| 883 | ** is true, also registers the result in the global table. | |
| 898 | 884 | ** Leaves resulting module on the top. |
| 899 | 885 | */ |
| 900 | 886 | LUALIB_API void luaL_requiref (lua_State *L, const char *modname, |
| 901 | 887 | lua_CFunction openf, int glb) { |
| 888 | lua_pushcfunction(L, openf); | |
| 889 | lua_pushstring(L, modname); /* argument to open function */ | |
| 890 | lua_call(L, 1, 1); /* open module */ | |
| 902 | 891 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); |
| 903 | lua_getfield(L, -1, modname); /* _LOADED[modname] */ | |
| 904 | if (!lua_toboolean(L, -1)) { /* package not already loaded? */ | |
| 905 | lua_pop(L, 1); /* remove field */ | |
| 906 | lua_pushcfunction(L, openf); | |
| 907 | lua_pushstring(L, modname); /* argument to open function */ | |
| 908 | lua_call(L, 1, 1); /* call 'openf' to open module */ | |
| 909 | lua_pushvalue(L, -1); /* make copy of module (call result) */ | |
| 910 | lua_setfield(L, -3, modname); /* _LOADED[modname] = module */ | |
| 911 | } | |
| 912 | lua_remove(L, -2); /* remove _LOADED table */ | |
| 892 | lua_pushvalue(L, -2); /* make copy of module (call result) */ | |
| 893 | lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ | |
| 894 | lua_pop(L, 1); /* remove _LOADED table */ | |
| 913 | 895 | if (glb) { |
| 914 | lua_pushvalue(L, -1); /* copy of mod | |
| 896 | lua_pushvalue(L, -1); /* copy of 'mod' */ | |
| 915 | 897 | lua_setglobal(L, modname); /* _G[modname] = module */ |
| 916 | 898 | } |
| 917 | 899 | } |
| r242899 | r242900 | |
| 926 | 908 | while ((wild = strstr(s, p)) != NULL) { |
| 927 | 909 | luaL_addlstring(&b, s, wild - s); /* push prefix */ |
| 928 | 910 | luaL_addstring(&b, r); /* push replacement in place of pattern */ |
| 929 | s = wild + l; /* continue after | |
| 911 | s = wild + l; /* continue after `p' */ | |
| 930 | 912 | } |
| 931 | 913 | luaL_addstring(&b, s); /* push last suffix */ |
| 932 | 914 | luaL_pushresult(&b); |
| r242899 | r242900 | |
| 946 | 928 | |
| 947 | 929 | |
| 948 | 930 | static int panic (lua_State *L) { |
| 949 | lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", | |
| 950 | lua_tostring(L, -1)); | |
| 931 | luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", | |
| 932 | lua_tostring(L, -1)); | |
| 951 | 933 | return 0; /* return to Lua to abort */ |
| 952 | 934 | } |
| 953 | 935 | |
| r242899 | r242900 | |
| 959 | 941 | } |
| 960 | 942 | |
| 961 | 943 | |
| 962 | LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver | |
| 944 | LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) { | |
| 963 | 945 | const lua_Number *v = lua_version(L); |
| 964 | if (sz != LUAL_NUMSIZES) /* check numeric types */ | |
| 965 | luaL_error(L, "core and library have incompatible numeric types"); | |
| 966 | 946 | if (v != lua_version(NULL)) |
| 967 | 947 | luaL_error(L, "multiple Lua VMs detected"); |
| 968 | 948 | else if (*v != ver) |
| 969 | 949 | luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", |
| 970 | 950 | ver, *v); |
| 951 | /* check conversions number -> integer types */ | |
| 952 | lua_pushnumber(L, -(lua_Number)0x1234); | |
| 953 | if (lua_tointeger(L, -1) != -0x1234 || | |
| 954 | lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234) | |
| 955 | luaL_error(L, "bad conversion number->int;" | |
| 956 | " must recompile Lua with proper settings"); | |
| 957 | lua_pop(L, 1); | |
| 971 | 958 | } |
| 972 | 959 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lauxlib.h,v 1.12 | |
| 2 | ** $Id: lauxlib.h,v 1.120.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 16 | 16 | |
| 17 | 17 | |
| 18 | 18 | |
| 19 | /* extra error code for | |
| 19 | /* extra error code for `luaL_load' */ | |
| 20 | 20 | #define LUA_ERRFILE (LUA_ERRERR+1) |
| 21 | 21 | |
| 22 | 22 | |
| r242899 | r242900 | |
| 26 | 26 | } luaL_Reg; |
| 27 | 27 | |
| 28 | 28 | |
| 29 | #define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) | |
| 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); | |
| 30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) | |
| 30 | 31 | |
| 31 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); | |
| 32 | #define luaL_checkversion(L) \ | |
| 33 | luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) | |
| 34 | ||
| 35 | 32 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); |
| 36 | 33 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); |
| 37 | 34 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); |
| 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 arg, | |
| 35 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); | |
| 36 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, | |
| 40 | 37 | size_t *l); |
| 41 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int | |
| 38 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, | |
| 42 | 39 | const char *def, size_t *l); |
| 43 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); | |
| 44 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); | |
| 40 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); | |
| 41 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); | |
| 45 | 42 | |
| 46 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); | |
| 47 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, | |
| 43 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); | |
| 44 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, | |
| 48 | 45 | lua_Integer def); |
| 46 | LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); | |
| 47 | LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, | |
| 48 | lua_Unsigned def); | |
| 49 | 49 | |
| 50 | 50 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); |
| 51 | LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); | |
| 52 | LUALIB_API void (luaL_checkany) (lua_State *L, int arg); | |
| 51 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); | |
| 52 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); | |
| 53 | 53 | |
| 54 | 54 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); |
| 55 | 55 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); |
| r242899 | r242900 | |
| 59 | 59 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); |
| 60 | 60 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); |
| 61 | 61 | |
| 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, | |
| 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, | |
| 63 | 63 | const char *const lst[]); |
| 64 | 64 | |
| 65 | 65 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); |
| r242899 | r242900 | |
| 83 | 83 | |
| 84 | 84 | LUALIB_API lua_State *(luaL_newstate) (void); |
| 85 | 85 | |
| 86 | LUALIB_API | |
| 86 | LUALIB_API int (luaL_len) (lua_State *L, int idx); | |
| 87 | 87 | |
| 88 | 88 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, |
| 89 | 89 | const char *r); |
| r242899 | r242900 | |
| 108 | 108 | #define luaL_newlibtable(L,l) \ |
| 109 | 109 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) |
| 110 | 110 | |
| 111 | #define luaL_newlib(L,l) \ | |
| 112 | (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) | |
| 111 | #define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) | |
| 113 | 112 | |
| 114 | #define luaL_argcheck(L, cond,arg,extramsg) \ | |
| 115 | ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) | |
| 113 | #define luaL_argcheck(L, cond,numarg,extramsg) \ | |
| 114 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) | |
| 116 | 115 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) |
| 117 | 116 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) |
| 117 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) | |
| 118 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) | |
| 119 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) | |
| 120 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) | |
| 118 | 121 | |
| 119 | 122 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) |
| 120 | 123 | |
| r242899 | r242900 | |
| 204 | 207 | #endif |
| 205 | 208 | |
| 206 | 209 | |
| 207 | /* | |
| 208 | ** {================================================================== | |
| 209 | ** "Abstraction Layer" for basic report of messages and errors | |
| 210 | ** =================================================================== | |
| 211 | */ | |
| 212 | ||
| 213 | /* print a string */ | |
| 214 | #if !defined(lua_writestring) | |
| 215 | #define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) | |
| 216 | 210 | #endif |
| 217 | 211 | |
| 218 | /* print a newline and flush the output */ | |
| 219 | #if !defined(lua_writeline) | |
| 220 | #define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) | |
| 221 | #endif | |
| 222 | 212 | |
| 223 | /* print an error message */ | |
| 224 | #if !defined(lua_writestringerror) | |
| 225 | #define lua_writestringerror(s,p) \ | |
| 226 | (fprintf(stderr, (s), (p)), fflush(stderr)) | |
| 227 | #endif | |
| 228 | ||
| 229 | /* }================================================================== */ | |
| 230 | ||
| 231 | ||
| 232 | /* | |
| 233 | ** {============================================================ | |
| 234 | ** Compatibility with deprecated conversions | |
| 235 | ** ============================================================= | |
| 236 | */ | |
| 237 | #if defined(LUA_COMPAT_APIINTCASTS) | |
| 238 | ||
| 239 | #define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) | |
| 240 | #define luaL_optunsigned(L,a,d) \ | |
| 241 | ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) | |
| 242 | ||
| 243 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) | |
| 244 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) | |
| 245 | ||
| 246 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) | |
| 247 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) | |
| 248 | ||
| 249 | #endif | |
| 250 | /* }============================================================ */ | |
| 251 | ||
| 252 | ||
| 253 | ||
| 254 | #endif | |
| 255 | ||
| 256 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1. | |
| 2 | ** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Basic library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lbaselib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | 8 | |
| 12 | ||
| 13 | 9 | #include <ctype.h> |
| 14 | 10 | #include <stdio.h> |
| 15 | 11 | #include <stdlib.h> |
| 16 | 12 | #include <string.h> |
| 17 | 13 | |
| 14 | #define lbaselib_c | |
| 15 | #define LUA_LIB | |
| 16 | ||
| 18 | 17 | #include "lua.h" |
| 19 | 18 | |
| 20 | 19 | #include "lauxlib.h" |
| r242899 | r242900 | |
| 33 | 32 | lua_call(L, 1, 1); |
| 34 | 33 | s = lua_tolstring(L, -1, &l); /* get result */ |
| 35 | 34 | if (s == NULL) |
| 36 | return luaL_error(L, "'tostring' must return a string to 'print'"); | |
| 37 | if (i>1) lua_writestring("\t", 1); | |
| 38 | lua_writestring(s, l); | |
| 35 | return luaL_error(L, | |
| 36 | LUA_QL("tostring") " must return a string to " LUA_QL("print")); | |
| 37 | if (i>1) luai_writestring("\t", 1); | |
| 38 | luai_writestring(s, l); | |
| 39 | 39 | lua_pop(L, 1); /* pop result */ |
| 40 | 40 | } |
| 41 | lua_writeline(); | |
| 41 | luai_writeline(); | |
| 42 | 42 | return 0; |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | |
| 46 | 46 | #define SPACECHARS " \f\n\r\t\v" |
| 47 | 47 | |
| 48 | static const char *b_str2int (const char *s, int base, lua_Integer *pn) { | |
| 49 | lua_Unsigned n = 0; | |
| 50 | int neg = 0; | |
| 51 | s += strspn(s, SPACECHARS); /* skip initial spaces */ | |
| 52 | if (*s == '-') { s++; neg = 1; } /* handle signal */ | |
| 53 | else if (*s == '+') s++; | |
| 54 | if (!isalnum((unsigned char)*s)) /* no digit? */ | |
| 55 | return NULL; | |
| 56 | do { | |
| 57 | int digit = (isdigit((unsigned char)*s)) ? *s - '0' | |
| 58 | : toupper((unsigned char)*s) - 'A' + 10; | |
| 59 | if (digit >= base) return NULL; /* invalid numeral */ | |
| 60 | n = n * base + digit; | |
| 61 | s++; | |
| 62 | } while (isalnum((unsigned char)*s)); | |
| 63 | s += strspn(s, SPACECHARS); /* skip trailing spaces */ | |
| 64 | *pn = (lua_Integer)((neg) ? (0u - n) : n); | |
| 65 | return s; | |
| 66 | } | |
| 67 | ||
| 68 | ||
| 69 | 48 | static int luaB_tonumber (lua_State *L) { |
| 70 | if (lua_isnoneornil(L, 2)) { /* standard conversion? */ | |
| 71 | luaL_checkany(L, 1); | |
| 72 | if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */ | |
| 73 | lua_settop(L, 1); /* yes; return it */ | |
| 49 | if (lua_isnoneornil(L, 2)) { /* standard conversion */ | |
| 50 | int isnum; | |
| 51 | lua_Number n = lua_tonumberx(L, 1, &isnum); | |
| 52 | if (isnum) { | |
| 53 | lua_pushnumber(L, n); | |
| 74 | 54 | return 1; |
| 75 | } | |
| 76 | else { | |
| 77 | size_t l; | |
| 78 | const char *s = lua_tolstring(L, 1, &l); | |
| 79 | if (s != NULL && lua_stringtonumber(L, s) == l + 1) | |
| 80 | return 1; /* successful conversion to number */ | |
| 81 | /* else not a number */ | |
| 82 | } | |
| 55 | } /* else not a number; must be something */ | |
| 56 | luaL_checkany(L, 1); | |
| 83 | 57 | } |
| 84 | 58 | else { |
| 85 | 59 | size_t l; |
| 86 | const char *s; | |
| 87 | lua_Integer n = 0; /* to avoid warnings */ | |
| 88 | lua_Integer base = luaL_checkinteger(L, 2); | |
| 89 | luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */ | |
| 90 | s = luaL_checklstring(L, 1, &l); | |
| 60 | const char *s = luaL_checklstring(L, 1, &l); | |
| 61 | const char *e = s + l; /* end point for 's' */ | |
| 62 | int base = luaL_checkint(L, 2); | |
| 63 | int neg = 0; | |
| 91 | 64 | luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); |
| 92 | if (b_str2int(s, (int)base, &n) == s + l) { | |
| 93 | lua_pushinteger(L, n); | |
| 94 | return 1; | |
| 65 | s += strspn(s, SPACECHARS); /* skip initial spaces */ | |
| 66 | if (*s == '-') { s++; neg = 1; } /* handle signal */ | |
| 67 | else if (*s == '+') s++; | |
| 68 | if (isalnum((unsigned char)*s)) { | |
| 69 | lua_Number n = 0; | |
| 70 | do { | |
| 71 | int digit = (isdigit((unsigned char)*s)) ? *s - '0' | |
| 72 | : toupper((unsigned char)*s) - 'A' + 10; | |
| 73 | if (digit >= base) break; /* invalid numeral; force a fail */ | |
| 74 | n = n * (lua_Number)base + (lua_Number)digit; | |
| 75 | s++; | |
| 76 | } while (isalnum((unsigned char)*s)); | |
| 77 | s += strspn(s, SPACECHARS); /* skip trailing spaces */ | |
| 78 | if (s == e) { /* no invalid trailing characters? */ | |
| 79 | lua_pushnumber(L, (neg) ? -n : n); | |
| 80 | return 1; | |
| 81 | } /* else not a number */ | |
| 95 | 82 | } /* else not a number */ |
| 96 | } | |
| 83 | } | |
| 97 | 84 | lua_pushnil(L); /* not a number */ |
| 98 | 85 | return 1; |
| 99 | 86 | } |
| 100 | 87 | |
| 101 | 88 | |
| 102 | 89 | static int luaB_error (lua_State *L) { |
| 103 | int level = | |
| 90 | int level = luaL_optint(L, 2, 1); | |
| 104 | 91 | lua_settop(L, 1); |
| 105 | 92 | if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ |
| 106 | 93 | luaL_where(L, level); |
| r242899 | r242900 | |
| 127 | 114 | luaL_checktype(L, 1, LUA_TTABLE); |
| 128 | 115 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, |
| 129 | 116 | "nil or table expected"); |
| 130 | if (luaL_getmetafield(L, 1, "__metatable") | |
| 117 | if (luaL_getmetafield(L, 1, "__metatable")) | |
| 131 | 118 | return luaL_error(L, "cannot change a protected metatable"); |
| 132 | 119 | lua_settop(L, 2); |
| 133 | 120 | lua_setmetatable(L, 1); |
| r242899 | r242900 | |
| 173 | 160 | static int luaB_collectgarbage (lua_State *L) { |
| 174 | 161 | static const char *const opts[] = {"stop", "restart", "collect", |
| 175 | 162 | "count", "step", "setpause", "setstepmul", |
| 176 | "isrunning", NULL}; | |
| 163 | "setmajorinc", "isrunning", "generational", "incremental", NULL}; | |
| 177 | 164 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, |
| 178 | 165 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, |
| 179 | LUA_GCISRUNNING}; | |
| 166 | LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; | |
| 180 | 167 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; |
| 181 | int ex = | |
| 168 | int ex = luaL_optint(L, 2, 0); | |
| 182 | 169 | int res = lua_gc(L, o, ex); |
| 183 | 170 | switch (o) { |
| 184 | 171 | case LUA_GCCOUNT: { |
| 185 | 172 | int b = lua_gc(L, LUA_GCCOUNTB, 0); |
| 186 | lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024)); | |
| 187 | return 1; | |
| 173 | lua_pushnumber(L, res + ((lua_Number)b/1024)); | |
| 174 | lua_pushinteger(L, b); | |
| 175 | return 2; | |
| 188 | 176 | } |
| 189 | 177 | case LUA_GCSTEP: case LUA_GCISRUNNING: { |
| 190 | 178 | lua_pushboolean(L, res); |
| r242899 | r242900 | |
| 198 | 186 | } |
| 199 | 187 | |
| 200 | 188 | |
| 201 | /* | |
| 202 | ** This function has all type names as upvalues, to maximize performance. | |
| 203 | */ | |
| 204 | 189 | static int luaB_type (lua_State *L) { |
| 205 | 190 | luaL_checkany(L, 1); |
| 206 | lua_push | |
| 191 | lua_pushstring(L, luaL_typename(L, 1)); | |
| 207 | 192 | return 1; |
| 208 | 193 | } |
| 209 | 194 | |
| 210 | 195 | |
| 211 | 196 | static int pairsmeta (lua_State *L, const char *method, int iszero, |
| 212 | 197 | lua_CFunction iter) { |
| 213 | if (luaL_getmetafield(L, 1, method) | |
| 198 | if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ | |
| 214 | 199 | luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ |
| 215 | 200 | lua_pushcfunction(L, iter); /* will return generator, */ |
| 216 | 201 | lua_pushvalue(L, 1); /* state, */ |
| r242899 | r242900 | |
| 242 | 227 | } |
| 243 | 228 | |
| 244 | 229 | |
| 245 | /* | |
| 246 | ** Traversal function for 'ipairs' for raw tables | |
| 247 | */ | |
| 248 | static int ipairsaux_raw (lua_State *L) { | |
| 249 | lua_Integer i = luaL_checkinteger(L, 2) + 1; | |
| 230 | static int ipairsaux (lua_State *L) { | |
| 231 | int i = luaL_checkint(L, 2); | |
| 250 | 232 | luaL_checktype(L, 1, LUA_TTABLE); |
| 233 | i++; /* next value */ | |
| 251 | 234 | lua_pushinteger(L, i); |
| 252 | return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2; | |
| 235 | lua_rawgeti(L, 1, i); | |
| 236 | return (lua_isnil(L, -1)) ? 1 : 2; | |
| 253 | 237 | } |
| 254 | 238 | |
| 255 | 239 | |
| 256 | /* | |
| 257 | ** Traversal function for 'ipairs' for tables with metamethods | |
| 258 | */ | |
| 259 | static int ipairsaux (lua_State *L) { | |
| 260 | lua_Integer i = luaL_checkinteger(L, 2) + 1; | |
| 261 | lua_pushinteger(L, i); | |
| 262 | return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; | |
| 263 | } | |
| 264 | ||
| 265 | ||
| 266 | /* | |
| 267 | ** This function will use either 'ipairsaux' or 'ipairsaux_raw' to | |
| 268 | ** traverse a table, depending on whether the table has metamethods | |
| 269 | ** that can affect the traversal. | |
| 270 | */ | |
| 271 | 240 | static int luaB_ipairs (lua_State *L) { |
| 272 | lua_CFunction iter = (luaL_getmetafield(L, 1, "__index") != LUA_TNIL) | |
| 273 | ? ipairsaux : ipairsaux_raw; | |
| 274 | #if defined(LUA_COMPAT_IPAIRS) | |
| 275 | return pairsmeta(L, "__ipairs", 1, iter); | |
| 276 | #else | |
| 277 | luaL_checkany(L, 1); | |
| 278 | lua_pushcfunction(L, iter); /* iteration function */ | |
| 279 | lua_pushvalue(L, 1); /* state */ | |
| 280 | lua_pushinteger(L, 0); /* initial value */ | |
| 281 | return 3; | |
| 282 | #endif | |
| 241 | return pairsmeta(L, "__ipairs", 1, ipairsaux); | |
| 283 | 242 | } |
| 284 | 243 | |
| 285 | 244 | |
| r242899 | r242900 | |
| 325 | 284 | |
| 326 | 285 | |
| 327 | 286 | /* |
| 328 | ** Reader for generic | |
| 287 | ** Reader for generic `load' function: `lua_load' uses the | |
| 329 | 288 | ** stack for internal stuff, so the reader cannot change the |
| 330 | 289 | ** stack top. Instead, it keeps its resulting string in a |
| 331 | 290 | ** reserved slot inside the stack. |
| r242899 | r242900 | |
| 369 | 328 | /* }====================================================== */ |
| 370 | 329 | |
| 371 | 330 | |
| 372 | static int dofilecont (lua_State *L, int d1, lua_KContext d2) { | |
| 373 | (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */ | |
| 331 | static int dofilecont (lua_State *L) { | |
| 374 | 332 | return lua_gettop(L) - 1; |
| 375 | 333 | } |
| 376 | 334 | |
| r242899 | r242900 | |
| 381 | 339 | if (luaL_loadfile(L, fname) != LUA_OK) |
| 382 | 340 | return lua_error(L); |
| 383 | 341 | lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); |
| 384 | return dofilecont(L | |
| 342 | return dofilecont(L); | |
| 385 | 343 | } |
| 386 | 344 | |
| 387 | 345 | |
| 388 | 346 | static int luaB_assert (lua_State *L) { |
| 389 | if (lua_toboolean(L, 1)) /* condition is true? */ | |
| 390 | return lua_gettop(L); /* return all arguments */ | |
| 391 | else { /* error */ | |
| 392 | luaL_checkany(L, 1); /* there must be a condition */ | |
| 393 | lua_remove(L, 1); /* remove it */ | |
| 394 | lua_pushliteral(L, "assertion failed!"); /* default message */ | |
| 395 | lua_settop(L, 1); /* leave only message (default if no other one) */ | |
| 396 | return luaB_error(L); /* call 'error' */ | |
| 397 | } | |
| 347 | if (!lua_toboolean(L, 1)) | |
| 348 | return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); | |
| 349 | return lua_gettop(L); | |
| 398 | 350 | } |
| 399 | 351 | |
| 400 | 352 | |
| r242899 | r242900 | |
| 405 | 357 | return 1; |
| 406 | 358 | } |
| 407 | 359 | else { |
| 408 | | |
| 360 | int i = luaL_checkint(L, 1); | |
| 409 | 361 | if (i < 0) i = n + i; |
| 410 | 362 | else if (i > n) i = n; |
| 411 | 363 | luaL_argcheck(L, 1 <= i, 1, "index out of range"); |
| 412 | return n - | |
| 364 | return n - i; | |
| 413 | 365 | } |
| 414 | 366 | } |
| 415 | 367 | |
| 416 | 368 | |
| 417 | /* | |
| 418 | ** Continuation function for 'pcall' and 'xpcall'. Both functions | |
| 419 | ** already pushed a 'true' before doing the call, so in case of success | |
| 420 | ** 'finishpcall' only has to return everything in the stack minus | |
| 421 | ** 'extra' values (where 'extra' is exactly the number of items to be | |
| 422 | ** ignored). | |
| 423 | */ | |
| 424 | static int finishpcall (lua_State *L, int status, lua_KContext extra) { | |
| 425 | if (status != LUA_OK && status != LUA_YIELD) { /* error? */ | |
| 426 | lua_pushboolean(L, 0); /* first result (false) */ | |
| 427 | lua_pushvalue(L, -2); /* error message */ | |
| 369 | static int finishpcall (lua_State *L, int status) { | |
| 370 | if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */ | |
| 371 | lua_settop(L, 0); /* create space for return values */ | |
| 372 | lua_pushboolean(L, 0); | |
| 373 | lua_pushstring(L, "stack overflow"); | |
| 428 | 374 | return 2; /* return false, msg */ |
| 429 | 375 | } |
| 430 | else | |
| 431 | return lua_gettop(L) - (int)extra; /* return all results */ | |
| 376 | lua_pushboolean(L, status); /* first result (status) */ | |
| 377 | lua_replace(L, 1); /* put first result in first slot */ | |
| 378 | return lua_gettop(L); | |
| 432 | 379 | } |
| 433 | 380 | |
| 434 | 381 | |
| 382 | static int pcallcont (lua_State *L) { | |
| 383 | int status = lua_getctx(L, NULL); | |
| 384 | return finishpcall(L, (status == LUA_YIELD)); | |
| 385 | } | |
| 386 | ||
| 387 | ||
| 435 | 388 | static int luaB_pcall (lua_State *L) { |
| 436 | 389 | int status; |
| 437 | 390 | luaL_checkany(L, 1); |
| 438 | lua_pushboolean(L, 1); /* first result if no errors */ | |
| 439 | lua_insert(L, 1); /* put it in place */ | |
| 440 | status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall); | |
| 441 | return finishpcall(L, status, 0); | |
| 391 | lua_pushnil(L); | |
| 392 | lua_insert(L, 1); /* create space for status result */ | |
| 393 | status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont); | |
| 394 | return finishpcall(L, (status == LUA_OK)); | |
| 442 | 395 | } |
| 443 | 396 | |
| 444 | 397 | |
| 445 | /* | |
| 446 | ** Do a protected call with error handling. After 'lua_rotate', the | |
| 447 | ** stack will have <f, err, true, f, [args...]>; so, the function passes | |
| 448 | ** 2 to 'finishpcall' to skip the 2 first values when returning results. | |
| 449 | */ | |
| 450 | 398 | static int luaB_xpcall (lua_State *L) { |
| 451 | 399 | int status; |
| 452 | 400 | int n = lua_gettop(L); |
| 453 | luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */ | |
| 454 | lua_pushboolean(L, 1); /* first result */ | |
| 455 | lua_pushvalue(L, 1); /* function */ | |
| 456 | lua_rotate(L, 3, 2); /* move them below function's arguments */ | |
| 457 | status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall); | |
| 458 | return finishpcall(L, status, 2); | |
| 401 | luaL_argcheck(L, n >= 2, 2, "value expected"); | |
| 402 | lua_pushvalue(L, 1); /* exchange function... */ | |
| 403 | lua_copy(L, 2, 1); /* ...and error handler */ | |
| 404 | lua_replace(L, 2); | |
| 405 | status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont); | |
| 406 | return finishpcall(L, (status == LUA_OK)); | |
| 459 | 407 | } |
| 460 | 408 | |
| 461 | 409 | |
| r242899 | r242900 | |
| 490 | 438 | {"setmetatable", luaB_setmetatable}, |
| 491 | 439 | {"tonumber", luaB_tonumber}, |
| 492 | 440 | {"tostring", luaB_tostring}, |
| 441 | {"type", luaB_type}, | |
| 493 | 442 | {"xpcall", luaB_xpcall}, |
| 494 | /* placeholders */ | |
| 495 | {"type", NULL}, | |
| 496 | {"_G", NULL}, | |
| 497 | {"_VERSION", NULL}, | |
| 498 | 443 | {NULL, NULL} |
| 499 | 444 | }; |
| 500 | 445 | |
| 501 | 446 | |
| 502 | 447 | LUAMOD_API int luaopen_base (lua_State *L) { |
| 503 | int i; | |
| 504 | /* open lib into global table */ | |
| 505 | lua_pushglobaltable(L); | |
| 506 | luaL_setfuncs(L, base_funcs, 0); | |
| 507 | 448 | /* set global _G */ |
| 508 | lua_pushvalue(L, -1); | |
| 449 | lua_pushglobaltable(L); | |
| 450 | lua_pushglobaltable(L); | |
| 509 | 451 | lua_setfield(L, -2, "_G"); |
| 510 | /* set global _VERSION */ | |
| 452 | /* open lib into global table */ | |
| 453 | luaL_setfuncs(L, base_funcs, 0); | |
| 511 | 454 | lua_pushliteral(L, LUA_VERSION); |
| 512 | lua_setfield(L, -2, "_VERSION"); | |
| 513 | /* set function 'type' with proper upvalues */ | |
| 514 | for (i = 0; i < LUA_NUMTAGS; i++) /* push all type names as upvalues */ | |
| 515 | lua_pushstring(L, lua_typename(L, i)); | |
| 516 | lua_pushcclosure(L, luaB_type, LUA_NUMTAGS); | |
| 517 | lua_setfield(L, -2, "type"); | |
| 455 | lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ | |
| 518 | 456 | return 1; |
| 519 | 457 | } |
| 520 | 458 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lbitlib.c,v 1. | |
| 2 | ** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $ | |
| 3 | 3 | ** Standard library for bitwise operations |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 7 | 7 | #define lbitlib_c |
| 8 | 8 | #define LUA_LIB |
| 9 | 9 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 10 | #include "lua.h" |
| 14 | 11 | |
| 15 | 12 | #include "lauxlib.h" |
| 16 | 13 | #include "lualib.h" |
| 17 | 14 | |
| 18 | 15 | |
| 19 | #if defined(LUA_COMPAT_BITLIB) /* { */ | |
| 20 | ||
| 21 | ||
| 22 | 16 | /* number of bits to consider in a number */ |
| 23 | 17 | #if !defined(LUA_NBITS) |
| 24 | 18 | #define LUA_NBITS 32 |
| 25 | 19 | #endif |
| 26 | 20 | |
| 27 | 21 | |
| 28 | /* | |
| 29 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must | |
| 30 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the | |
| 31 | ** number of bits in a lua_Unsigned.) | |
| 32 | */ | |
| 33 | 22 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) |
| 34 | 23 | |
| 35 | ||
| 36 | 24 | /* macro to trim extra bits */ |
| 37 | 25 | #define trim(x) ((x) & ALLONES) |
| 38 | 26 | |
| r242899 | r242900 | |
| 41 | 29 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) |
| 42 | 30 | |
| 43 | 31 | |
| 32 | typedef lua_Unsigned b_uint; | |
| 44 | 33 | |
| 45 | static lua_Unsigned andaux (lua_State *L) { | |
| 34 | ||
| 35 | ||
| 36 | static b_uint andaux (lua_State *L) { | |
| 46 | 37 | int i, n = lua_gettop(L); |
| 47 | | |
| 38 | b_uint r = ~(b_uint)0; | |
| 48 | 39 | for (i = 1; i <= n; i++) |
| 49 | 40 | r &= luaL_checkunsigned(L, i); |
| 50 | 41 | return trim(r); |
| r242899 | r242900 | |
| 52 | 43 | |
| 53 | 44 | |
| 54 | 45 | static int b_and (lua_State *L) { |
| 55 | | |
| 46 | b_uint r = andaux(L); | |
| 56 | 47 | lua_pushunsigned(L, r); |
| 57 | 48 | return 1; |
| 58 | 49 | } |
| 59 | 50 | |
| 60 | 51 | |
| 61 | 52 | static int b_test (lua_State *L) { |
| 62 | | |
| 53 | b_uint r = andaux(L); | |
| 63 | 54 | lua_pushboolean(L, r != 0); |
| 64 | 55 | return 1; |
| 65 | 56 | } |
| r242899 | r242900 | |
| 67 | 58 | |
| 68 | 59 | static int b_or (lua_State *L) { |
| 69 | 60 | int i, n = lua_gettop(L); |
| 70 | | |
| 61 | b_uint r = 0; | |
| 71 | 62 | for (i = 1; i <= n; i++) |
| 72 | 63 | r |= luaL_checkunsigned(L, i); |
| 73 | 64 | lua_pushunsigned(L, trim(r)); |
| r242899 | r242900 | |
| 77 | 68 | |
| 78 | 69 | static int b_xor (lua_State *L) { |
| 79 | 70 | int i, n = lua_gettop(L); |
| 80 | | |
| 71 | b_uint r = 0; | |
| 81 | 72 | for (i = 1; i <= n; i++) |
| 82 | 73 | r ^= luaL_checkunsigned(L, i); |
| 83 | 74 | lua_pushunsigned(L, trim(r)); |
| r242899 | r242900 | |
| 86 | 77 | |
| 87 | 78 | |
| 88 | 79 | static int b_not (lua_State *L) { |
| 89 | | |
| 80 | b_uint r = ~luaL_checkunsigned(L, 1); | |
| 90 | 81 | lua_pushunsigned(L, trim(r)); |
| 91 | 82 | return 1; |
| 92 | 83 | } |
| 93 | 84 | |
| 94 | 85 | |
| 95 | static int b_shift (lua_State *L, | |
| 86 | static int b_shift (lua_State *L, b_uint r, int i) { | |
| 96 | 87 | if (i < 0) { /* shift right? */ |
| 97 | 88 | i = -i; |
| 98 | 89 | r = trim(r); |
| r242899 | r242900 | |
| 110 | 101 | |
| 111 | 102 | |
| 112 | 103 | static int b_lshift (lua_State *L) { |
| 113 | return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint | |
| 104 | return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); | |
| 114 | 105 | } |
| 115 | 106 | |
| 116 | 107 | |
| 117 | 108 | static int b_rshift (lua_State *L) { |
| 118 | return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint | |
| 109 | return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); | |
| 119 | 110 | } |
| 120 | 111 | |
| 121 | 112 | |
| 122 | 113 | static int b_arshift (lua_State *L) { |
| 123 | lua_Unsigned r = luaL_checkunsigned(L, 1); | |
| 124 | lua_Integer i = luaL_checkinteger(L, 2); | |
| 125 | if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) | |
| 114 | b_uint r = luaL_checkunsigned(L, 1); | |
| 115 | int i = luaL_checkint(L, 2); | |
| 116 | if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) | |
| 126 | 117 | return b_shift(L, r, -i); |
| 127 | 118 | else { /* arithmetic shift for 'negative' number */ |
| 128 | 119 | if (i >= LUA_NBITS) r = ALLONES; |
| 129 | 120 | else |
| 130 | r = trim((r >> i) | ~( | |
| 121 | r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ | |
| 131 | 122 | lua_pushunsigned(L, r); |
| 132 | 123 | return 1; |
| 133 | 124 | } |
| 134 | 125 | } |
| 135 | 126 | |
| 136 | 127 | |
| 137 | static int b_rot (lua_State *L, lua_Integer d) { | |
| 138 | lua_Unsigned r = luaL_checkunsigned(L, 1); | |
| 139 | int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ | |
| 128 | static int b_rot (lua_State *L, int i) { | |
| 129 | b_uint r = luaL_checkunsigned(L, 1); | |
| 130 | i &= (LUA_NBITS - 1); /* i = i % NBITS */ | |
| 140 | 131 | r = trim(r); |
| 141 | 132 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ |
| 142 | 133 | r = (r << i) | (r >> (LUA_NBITS - i)); |
| r242899 | r242900 | |
| 146 | 137 | |
| 147 | 138 | |
| 148 | 139 | static int b_lrot (lua_State *L) { |
| 149 | return b_rot(L, luaL_checkint | |
| 140 | return b_rot(L, luaL_checkint(L, 2)); | |
| 150 | 141 | } |
| 151 | 142 | |
| 152 | 143 | |
| 153 | 144 | static int b_rrot (lua_State *L) { |
| 154 | return b_rot(L, -luaL_checkint | |
| 145 | return b_rot(L, -luaL_checkint(L, 2)); | |
| 155 | 146 | } |
| 156 | 147 | |
| 157 | 148 | |
| r242899 | r242900 | |
| 162 | 153 | ** 'width' being used uninitialized.) |
| 163 | 154 | */ |
| 164 | 155 | static int fieldargs (lua_State *L, int farg, int *width) { |
| 165 | lua_Integer f = luaL_checkinteger(L, farg); | |
| 166 | lua_Integer w = luaL_optinteger(L, farg + 1, 1); | |
| 156 | int f = luaL_checkint(L, farg); | |
| 157 | int w = luaL_optint(L, farg + 1, 1); | |
| 167 | 158 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); |
| 168 | 159 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); |
| 169 | 160 | if (f + w > LUA_NBITS) |
| 170 | 161 | luaL_error(L, "trying to access non-existent bits"); |
| 171 | *width = (int)w; | |
| 172 | return (int)f; | |
| 162 | *width = w; | |
| 163 | return f; | |
| 173 | 164 | } |
| 174 | 165 | |
| 175 | 166 | |
| 176 | 167 | static int b_extract (lua_State *L) { |
| 177 | 168 | int w; |
| 178 | | |
| 169 | b_uint r = luaL_checkunsigned(L, 1); | |
| 179 | 170 | int f = fieldargs(L, 2, &w); |
| 180 | 171 | r = (r >> f) & mask(w); |
| 181 | 172 | lua_pushunsigned(L, r); |
| r242899 | r242900 | |
| 185 | 176 | |
| 186 | 177 | static int b_replace (lua_State *L) { |
| 187 | 178 | int w; |
| 188 | lua_Unsigned r = trim(luaL_checkunsigned(L, 1)); | |
| 189 | lua_Unsigned v = luaL_checkunsigned(L, 2); | |
| 179 | b_uint r = luaL_checkunsigned(L, 1); | |
| 180 | b_uint v = luaL_checkunsigned(L, 2); | |
| 190 | 181 | int f = fieldargs(L, 3, &w); |
| 191 | 182 | int m = mask(w); |
| 192 | 183 | v &= m; /* erase bits outside given width */ |
| r242899 | r242900 | |
| 219 | 210 | return 1; |
| 220 | 211 | } |
| 221 | 212 | |
| 222 | ||
| 223 | #else /* }{ */ | |
| 224 | ||
| 225 | ||
| 226 | LUAMOD_API int luaopen_bit32 (lua_State *L) { | |
| 227 | return luaL_error(L, "library 'bit32' has been deprecated"); | |
| 228 | } | |
| 229 | ||
| 230 | #endif /* } */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lcode.c,v 2. | |
| 2 | ** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lcode_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <math.h> | |
| 14 | 8 | #include <stdlib.h> |
| 15 | 9 | |
| 10 | #define lcode_c | |
| 11 | #define LUA_CORE | |
| 12 | ||
| 16 | 13 | #include "lua.h" |
| 17 | 14 | |
| 18 | 15 | #include "lcode.h" |
| r242899 | r242900 | |
| 29 | 26 | #include "lvm.h" |
| 30 | 27 | |
| 31 | 28 | |
| 32 | /* Maximum number of registers in a Lua function */ | |
| 33 | #define MAXREGS 250 | |
| 34 | ||
| 35 | ||
| 36 | 29 | #define hasjumps(e) ((e)->t != (e)->f) |
| 37 | 30 | |
| 38 | 31 | |
| 39 | static int tonumeral(expdesc *e, TValue *v) { | |
| 40 | if (e->t != NO_JUMP || e->f != NO_JUMP) | |
| 41 | return 0; /* not a numeral */ | |
| 42 | switch (e->k) { | |
| 43 | case VKINT: | |
| 44 | if (v) setivalue(v, e->u.ival); | |
| 45 | return 1; | |
| 46 | case VKFLT: | |
| 47 | if (v) setfltvalue(v, e->u.nval); | |
| 48 | return 1; | |
| 49 | default: return 0; | |
| 50 | } | |
| 32 | static int isnumeral(expdesc *e) { | |
| 33 | return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); | |
| 51 | 34 | } |
| 52 | 35 | |
| 53 | 36 | |
| r242899 | r242900 | |
| 105 | 88 | |
| 106 | 89 | |
| 107 | 90 | /* |
| 108 | ** returns current | |
| 91 | ** returns current `pc' and marks it as a jump target (to avoid wrong | |
| 109 | 92 | ** optimizations with consecutive instructions not in the same basic block). |
| 110 | 93 | */ |
| 111 | 94 | int luaK_getlabel (FuncState *fs) { |
| r242899 | r242900 | |
| 193 | 176 | } |
| 194 | 177 | |
| 195 | 178 | |
| 196 | void luaK_patchclose (FuncState *fs, int list, int level) { | |
| 179 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { | |
| 197 | 180 | level++; /* argument is +1 to reserve 0 as non-op */ |
| 198 | 181 | while (list != NO_JUMP) { |
| 199 | 182 | int next = getjump(fs, list); |
| r242899 | r242900 | |
| 228 | 211 | |
| 229 | 212 | static int luaK_code (FuncState *fs, Instruction i) { |
| 230 | 213 | Proto *f = fs->f; |
| 231 | dischargejpc(fs); /* | |
| 214 | dischargejpc(fs); /* `pc' will change */ | |
| 232 | 215 | /* put new instruction in code array */ |
| 233 | 216 | luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, |
| 234 | 217 | MAX_INT, "opcodes"); |
| r242899 | r242900 | |
| 278 | 261 | void luaK_checkstack (FuncState *fs, int n) { |
| 279 | 262 | int newstack = fs->freereg + n; |
| 280 | 263 | if (newstack > fs->f->maxstacksize) { |
| 281 | if (newstack >= MAX | |
| 264 | if (newstack >= MAXSTACK) | |
| 282 | 265 | luaX_syntaxerror(fs->ls, "function or expression too complex"); |
| 283 | 266 | fs->f->maxstacksize = cast_byte(newstack); |
| 284 | 267 | } |
| r242899 | r242900 | |
| 305 | 288 | } |
| 306 | 289 | |
| 307 | 290 | |
| 308 | /* | |
| 309 | ** Use scanner's table to cache position of constants in constant list | |
| 310 | ** and try to reuse constants | |
| 311 | */ | |
| 312 | 291 | static int addk (FuncState *fs, TValue *key, TValue *v) { |
| 313 | 292 | lua_State *L = fs->ls->L; |
| 293 | TValue *idx = luaH_set(L, fs->h, key); | |
| 314 | 294 | Proto *f = fs->f; |
| 315 | TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ | |
| 316 | 295 | int k, oldsize; |
| 317 | if (ttisinteger(idx)) { /* is there an index there? */ | |
| 318 | k = cast_int(ivalue(idx)); | |
| 319 | /* correct value? (warning: must distinguish floats from integers!) */ | |
| 320 | if (k < fs->nk && ttype(&f->k[k]) == ttype(v) && | |
| 321 | luaV_rawequalobj(&f->k[k], v)) | |
| 322 | return k; /* reuse index */ | |
| 296 | if (ttisnumber(idx)) { | |
| 297 | lua_Number n = nvalue(idx); | |
| 298 | lua_number2int(k, n); | |
| 299 | if (luaV_rawequalobj(&f->k[k], v)) | |
| 300 | return k; | |
| 301 | /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); | |
| 302 | go through and create a new entry for this value */ | |
| 323 | 303 | } |
| 324 | 304 | /* constant not found; create a new entry */ |
| 325 | 305 | oldsize = f->sizek; |
| 326 | 306 | k = fs->nk; |
| 327 | 307 | /* numerical value does not need GC barrier; |
| 328 | 308 | table has no metatable, so it does not need to invalidate cache */ |
| 329 | set | |
| 309 | setnvalue(idx, cast_num(k)); | |
| 330 | 310 | luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); |
| 331 | 311 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); |
| 332 | 312 | setobj(L, &f->k[k], v); |
| r242899 | r242900 | |
| 343 | 323 | } |
| 344 | 324 | |
| 345 | 325 | |
| 346 | /* | |
| 347 | ** Integers use userdata as keys to avoid collision with floats with same | |
| 348 | ** value; conversion to 'void*' used only for hashing, no "precision" | |
| 349 | ** problems | |
| 350 | */ | |
| 351 | int luaK_intK (FuncState *fs, lua_Integer n) { | |
| 352 | TValue k, o; | |
| 353 | setpvalue(&k, cast(void*, cast(size_t, n))); | |
| 354 | setivalue(&o, n); | |
| 355 | return addk(fs, &k, &o); | |
| 356 | } | |
| 357 | ||
| 358 | ||
| 359 | static int luaK_numberK (FuncState *fs, lua_Number r) { | |
| 326 | int luaK_numberK (FuncState *fs, lua_Number r) { | |
| 327 | int n; | |
| 328 | lua_State *L = fs->ls->L; | |
| 360 | 329 | TValue o; |
| 361 | setfltvalue(&o, r); | |
| 362 | return addk(fs, &o, &o); | |
| 330 | setnvalue(&o, r); | |
| 331 | if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */ | |
| 332 | /* use raw representation as key to avoid numeric problems */ | |
| 333 | setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); | |
| 334 | n = addk(fs, L->top - 1, &o); | |
| 335 | L->top--; | |
| 336 | } | |
| 337 | else | |
| 338 | n = addk(fs, &o, &o); /* regular case */ | |
| 339 | return n; | |
| 363 | 340 | } |
| 364 | 341 | |
| 365 | 342 | |
| r242899 | r242900 | |
| 374 | 351 | TValue k, v; |
| 375 | 352 | setnilvalue(&v); |
| 376 | 353 | /* cannot use nil as key; instead use table itself to represent nil */ |
| 377 | sethvalue(fs->ls->L, &k, fs-> | |
| 354 | sethvalue(fs->ls->L, &k, fs->h); | |
| 378 | 355 | return addk(fs, &k, &v); |
| 379 | 356 | } |
| 380 | 357 | |
| r242899 | r242900 | |
| 456 | 433 | luaK_codek(fs, reg, e->u.info); |
| 457 | 434 | break; |
| 458 | 435 | } |
| 459 | case VK | |
| 436 | case VKNUM: { | |
| 460 | 437 | luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); |
| 461 | 438 | break; |
| 462 | 439 | } |
| 463 | case VKINT: { | |
| 464 | luaK_codek(fs, reg, luaK_intK(fs, e->u.ival)); | |
| 465 | break; | |
| 466 | } | |
| 467 | 440 | case VRELOCABLE: { |
| 468 | 441 | Instruction *pc = &getcode(fs, e); |
| 469 | 442 | SETARG_A(*pc, reg); |
| r242899 | r242900 | |
| 495 | 468 | static void exp2reg (FuncState *fs, expdesc *e, int reg) { |
| 496 | 469 | discharge2reg(fs, e, reg); |
| 497 | 470 | if (e->k == VJMP) |
| 498 | luaK_concat(fs, &e->t, e->u.info); /* put this jump in | |
| 471 | luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ | |
| 499 | 472 | if (hasjumps(e)) { |
| 500 | 473 | int final; /* position after whole expression */ |
| 501 | 474 | int p_f = NO_JUMP; /* position of an eventual LOAD false */ |
| r242899 | r242900 | |
| 565 | 538 | } |
| 566 | 539 | else break; |
| 567 | 540 | } |
| 568 | case VKINT: { | |
| 569 | e->u.info = luaK_intK(fs, e->u.ival); | |
| 570 | e->k = VK; | |
| 571 | goto vk; | |
| 572 | } | |
| 573 | case VKFLT: { | |
| 541 | case VKNUM: { | |
| 574 | 542 | e->u.info = luaK_numberK(fs, e->u.nval); |
| 575 | 543 | e->k = VK; |
| 576 | 544 | /* go through */ |
| 577 | 545 | } |
| 578 | 546 | case VK: { |
| 579 | vk: | |
| 580 | if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ | |
| 547 | if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ | |
| 581 | 548 | return RKASK(e->u.info); |
| 582 | 549 | else break; |
| 583 | 550 | } |
| r242899 | r242900 | |
| 660 | 627 | pc = e->u.info; |
| 661 | 628 | break; |
| 662 | 629 | } |
| 663 | case VK: case VK | |
| 630 | case VK: case VKNUM: case VTRUE: { | |
| 664 | 631 | pc = NO_JUMP; /* always true; do nothing */ |
| 665 | 632 | break; |
| 666 | 633 | } |
| r242899 | r242900 | |
| 669 | 636 | break; |
| 670 | 637 | } |
| 671 | 638 | } |
| 672 | luaK_concat(fs, &e->f, pc); /* insert last jump in | |
| 639 | luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ | |
| 673 | 640 | luaK_patchtohere(fs, e->t); |
| 674 | 641 | e->t = NO_JUMP; |
| 675 | 642 | } |
| r242899 | r242900 | |
| 692 | 659 | break; |
| 693 | 660 | } |
| 694 | 661 | } |
| 695 | luaK_concat(fs, &e->t, pc); /* insert last jump in | |
| 662 | luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ | |
| 696 | 663 | luaK_patchtohere(fs, e->f); |
| 697 | 664 | e->f = NO_JUMP; |
| 698 | 665 | } |
| r242899 | r242900 | |
| 705 | 672 | e->k = VTRUE; |
| 706 | 673 | break; |
| 707 | 674 | } |
| 708 | case VK: case VK | |
| 675 | case VK: case VKNUM: case VTRUE: { | |
| 709 | 676 | e->k = VFALSE; |
| 710 | 677 | break; |
| 711 | 678 | } |
| r242899 | r242900 | |
| 743 | 710 | } |
| 744 | 711 | |
| 745 | 712 | |
| 746 | /* | |
| 747 | ** return false if folding can raise an error | |
| 748 | */ | |
| 749 | static int validop (int op, TValue *v1, TValue *v2) { | |
| 750 | switch (op) { | |
| 751 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: | |
| 752 | case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ | |
| 753 | lua_Integer i; | |
| 754 | return (tointeger(v1, &i) && tointeger(v2, &i)); | |
| 755 | } | |
| 756 | case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ | |
| 757 | return (nvalue(v2) != 0); | |
| 758 | default: return 1; /* everything else is valid */ | |
| 759 | } | |
| 760 | } | |
| 761 | ||
| 762 | ||
| 763 | /* | |
| 764 | ** Try to "constant-fold" an operation; return 1 iff successful | |
| 765 | */ | |
| 766 | static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) { | |
| 767 | TValue v1, v2, res; | |
| 768 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) | |
| 769 | return 0; /* non-numeric operands or not safe to fold */ | |
| 770 | luaO_arith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ | |
| 771 | if (ttisinteger(&res)) { | |
| 772 | e1->k = VKINT; | |
| 773 | e1->u.ival = ivalue(&res); | |
| 774 | } | |
| 775 | else { /* folds neither NaN nor 0.0 (to avoid collapsing with -0.0) */ | |
| 776 | lua_Number n = fltvalue(&res); | |
| 777 | if (luai_numisnan(n) || n == 0) | |
| 778 | return 0; | |
| 779 | e1->k = VKFLT; | |
| 780 | e1->u.nval = n; | |
| 781 | } | |
| 713 | static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { | |
| 714 | lua_Number r; | |
| 715 | if (!isnumeral(e1) || !isnumeral(e2)) return 0; | |
| 716 | if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) | |
| 717 | return 0; /* do not attempt to divide by 0 */ | |
| 718 | r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); | |
| 719 | e1->u.nval = r; | |
| 782 | 720 | return 1; |
| 783 | 721 | } |
| 784 | 722 | |
| 785 | 723 | |
| 786 | /* | |
| 787 | ** Code for binary and unary expressions that "produce values" | |
| 788 | ** (arithmetic operations, bitwise operations, concat, length). First | |
| 789 | ** try to do constant folding (only for numeric [arithmetic and | |
| 790 | ** bitwise] operations, which is what 'lua_arith' accepts). | |
| 791 | ** Expression to produce final result will be encoded in 'e1'. | |
| 792 | */ | |
| 793 | static void codeexpval (FuncState *fs, OpCode op, | |
| 794 | expdesc *e1, expdesc *e2, int line) { | |
| 795 | lua_assert(op >= OP_ADD); | |
| 796 | if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) | |
| 797 | return; /* result has been folded */ | |
| 724 | static void codearith (FuncState *fs, OpCode op, | |
| 725 | expdesc *e1, expdesc *e2, int line) { | |
| 726 | if (constfolding(op, e1, e2)) | |
| 727 | return; | |
| 798 | 728 | else { |
| 799 | int o1, o2; | |
| 800 | /* move operands to registers (if needed) */ | |
| 801 | if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */ | |
| 802 | o2 = 0; /* no second expression */ | |
| 803 | o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ | |
| 804 | } | |
| 805 | else { /* regular case (binary operators) */ | |
| 806 | o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ | |
| 807 | o1 = luaK_exp2RK(fs, e1); | |
| 808 | } | |
| 809 | if (o1 > o2) { /* free registers in proper order */ | |
| 729 | int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; | |
| 730 | int o1 = luaK_exp2RK(fs, e1); | |
| 731 | if (o1 > o2) { | |
| 810 | 732 | freeexp(fs, e1); |
| 811 | 733 | freeexp(fs, e2); |
| 812 | 734 | } |
| r242899 | r242900 | |
| 814 | 736 | freeexp(fs, e2); |
| 815 | 737 | freeexp(fs, e1); |
| 816 | 738 | } |
| 817 | e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */ | |
| 818 | e1->k = VRELOCABLE; /* all those operations are relocable */ | |
| 739 | e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); | |
| 740 | e1->k = VRELOCABLE; | |
| 819 | 741 | luaK_fixline(fs, line); |
| 820 | 742 | } |
| 821 | 743 | } |
| r242899 | r242900 | |
| 828 | 750 | freeexp(fs, e2); |
| 829 | 751 | freeexp(fs, e1); |
| 830 | 752 | if (cond == 0 && op != OP_EQ) { |
| 831 | int temp; /* exchange args to replace by | |
| 753 | int temp; /* exchange args to replace by `<' or `<=' */ | |
| 832 | 754 | temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ |
| 833 | 755 | cond = 1; |
| 834 | 756 | } |
| r242899 | r242900 | |
| 839 | 761 | |
| 840 | 762 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { |
| 841 | 763 | expdesc e2; |
| 842 | e2.t = e2.f = NO_JUMP; e2.k = VK | |
| 764 | e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; | |
| 843 | 765 | switch (op) { |
| 844 | case OPR_MINUS: case OPR_BNOT: case OPR_LEN: { | |
| 845 | codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line); | |
| 766 | case OPR_MINUS: { | |
| 767 | if (isnumeral(e)) /* minus constant? */ | |
| 768 | e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ | |
| 769 | else { | |
| 770 | luaK_exp2anyreg(fs, e); | |
| 771 | codearith(fs, OP_UNM, e, &e2, line); | |
| 772 | } | |
| 846 | 773 | break; |
| 847 | 774 | } |
| 848 | 775 | case OPR_NOT: codenot(fs, e); break; |
| 776 | case OPR_LEN: { | |
| 777 | luaK_exp2anyreg(fs, e); /* cannot operate on constants */ | |
| 778 | codearith(fs, OP_LEN, e, &e2, line); | |
| 779 | break; | |
| 780 | } | |
| 849 | 781 | default: lua_assert(0); |
| 850 | 782 | } |
| 851 | 783 | } |
| r242899 | r242900 | |
| 862 | 794 | break; |
| 863 | 795 | } |
| 864 | 796 | case OPR_CONCAT: { |
| 865 | luaK_exp2nextreg(fs, v); /* operand must be on the | |
| 797 | luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ | |
| 866 | 798 | break; |
| 867 | 799 | } |
| 868 | case OPR_ADD: case OPR_SUB: | |
| 869 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: | |
| 870 | case OPR_MOD: case OPR_POW: | |
| 871 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | |
| 872 | case OPR_SHL: case OPR_SHR: { | |
| 873 | if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); | |
| 800 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: | |
| 801 | case OPR_MOD: case OPR_POW: { | |
| 802 | if (!isnumeral(v)) luaK_exp2RK(fs, v); | |
| 874 | 803 | break; |
| 875 | 804 | } |
| 876 | 805 | default: { |
| r242899 | r242900 | |
| 908 | 837 | } |
| 909 | 838 | else { |
| 910 | 839 | luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ |
| 911 | code | |
| 840 | codearith(fs, OP_CONCAT, e1, e2, line); | |
| 912 | 841 | } |
| 913 | 842 | break; |
| 914 | 843 | } |
| 915 | 844 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: |
| 916 | case OPR_IDIV: case OPR_MOD: case OPR_POW: | |
| 917 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | |
| 918 | case OPR_SHL: case OPR_SHR: { | |
| 919 | codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line); | |
| 845 | case OPR_MOD: case OPR_POW: { | |
| 846 | codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); | |
| 920 | 847 | break; |
| 921 | 848 | } |
| 922 | 849 | case OPR_EQ: case OPR_LT: case OPR_LE: { |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lcode.h,v 1. | |
| 2 | ** $Id: lcode.h,v 1.58.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 24 | 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) |
| 25 | 25 | */ |
| 26 | 26 | typedef enum BinOpr { |
| 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, | |
| 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, | |
| 32 | 28 | OPR_CONCAT, |
| 33 | 29 | OPR_EQ, OPR_LT, OPR_LE, |
| 34 | 30 | OPR_NE, OPR_GT, OPR_GE, |
| r242899 | r242900 | |
| 37 | 33 | } BinOpr; |
| 38 | 34 | |
| 39 | 35 | |
| 40 | typedef enum UnOpr { OPR_MINUS, OPR_ | |
| 36 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | |
| 41 | 37 | |
| 42 | 38 | |
| 43 | 39 | #define getcode(fs,e) ((fs)->f->code[(e)->u.info]) |
| r242899 | r242900 | |
| 56 | 52 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); |
| 57 | 53 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); |
| 58 | 54 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); |
| 59 | LUAI_FUNC int luaK_ | |
| 55 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); | |
| 60 | 56 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); |
| 61 | 57 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); |
| 62 | 58 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lcorolib.c,v 1. | |
| 2 | ** $Id: lcorolib.c,v 1.5.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Coroutine Library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lcorolib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include | |
| 8 | #include <stdlib.h> | |
| 11 | 9 | |
| 12 | 10 | |
| 13 | #include <stdlib.h> | |
| 11 | #define lcorolib_c | |
| 12 | #define LUA_LIB | |
| 14 | 13 | |
| 15 | 14 | #include "lua.h" |
| 16 | 15 | |
| r242899 | r242900 | |
| 18 | 17 | #include "lualib.h" |
| 19 | 18 | |
| 20 | 19 | |
| 21 | static lua_State *getco (lua_State *L) { | |
| 22 | lua_State *co = lua_tothread(L, 1); | |
| 23 | luaL_argcheck(L, co, 1, "thread expected"); | |
| 24 | return co; | |
| 25 | } | |
| 26 | ||
| 27 | ||
| 28 | 20 | static int auxresume (lua_State *L, lua_State *co, int narg) { |
| 29 | 21 | int status; |
| 30 | 22 | if (!lua_checkstack(co, narg)) { |
| r242899 | r242900 | |
| 55 | 47 | |
| 56 | 48 | |
| 57 | 49 | static int luaB_coresume (lua_State *L) { |
| 58 | lua_State *co = | |
| 50 | lua_State *co = lua_tothread(L, 1); | |
| 59 | 51 | int r; |
| 52 | luaL_argcheck(L, co, 1, "coroutine expected"); | |
| 60 | 53 | r = auxresume(L, co, lua_gettop(L) - 1); |
| 61 | 54 | if (r < 0) { |
| 62 | 55 | lua_pushboolean(L, 0); |
| r242899 | r242900 | |
| 66 | 59 | else { |
| 67 | 60 | lua_pushboolean(L, 1); |
| 68 | 61 | lua_insert(L, -(r + 1)); |
| 69 | return r + 1; /* return true + | |
| 62 | return r + 1; /* return true + `resume' returns */ | |
| 70 | 63 | } |
| 71 | 64 | } |
| 72 | 65 | |
| r242899 | r242900 | |
| 109 | 102 | |
| 110 | 103 | |
| 111 | 104 | static int luaB_costatus (lua_State *L) { |
| 112 | lua_State *co = getco(L); | |
| 105 | lua_State *co = lua_tothread(L, 1); | |
| 106 | luaL_argcheck(L, co, 1, "coroutine expected"); | |
| 113 | 107 | if (L == co) lua_pushliteral(L, "running"); |
| 114 | 108 | else { |
| 115 | 109 | switch (lua_status(co)) { |
| r242899 | r242900 | |
| 135 | 129 | } |
| 136 | 130 | |
| 137 | 131 | |
| 138 | static int luaB_yieldable (lua_State *L) { | |
| 139 | lua_pushboolean(L, lua_isyieldable(L)); | |
| 140 | return 1; | |
| 141 | } | |
| 142 | ||
| 143 | ||
| 144 | 132 | static int luaB_corunning (lua_State *L) { |
| 145 | 133 | int ismain = lua_pushthread(L); |
| 146 | 134 | lua_pushboolean(L, ismain); |
| r242899 | r242900 | |
| 155 | 143 | {"status", luaB_costatus}, |
| 156 | 144 | {"wrap", luaB_cowrap}, |
| 157 | 145 | {"yield", luaB_yield}, |
| 158 | {"isyieldable", luaB_yieldable}, | |
| 159 | 146 | {NULL, NULL} |
| 160 | 147 | }; |
| 161 | 148 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lctype.c,v 1.1 | |
| 2 | ** $Id: lctype.c,v 1.11.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** 'ctype' functions for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 7 | 7 | #define lctype_c |
| 8 | 8 | #define LUA_CORE |
| 9 | 9 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 10 | #include "lctype.h" |
| 14 | 11 | |
| 15 | 12 | #if !LUA_USE_CTYPE /* { */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lctype.h,v 1.12 201 | |
| 2 | ** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** 'ctype' functions for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ldblib.c,v 1.1 | |
| 2 | ** $Id: ldblib.c,v 1.132.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Interface from Lua to its debug API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define ldblib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <stdio.h> |
| 14 | 9 | #include <stdlib.h> |
| 15 | 10 | #include <string.h> |
| 16 | 11 | |
| 12 | #define ldblib_c | |
| 13 | #define LUA_LIB | |
| 14 | ||
| 17 | 15 | #include "lua.h" |
| 18 | 16 | |
| 19 | 17 | #include "lauxlib.h" |
| 20 | 18 | #include "lualib.h" |
| 21 | 19 | |
| 22 | 20 | |
| 23 | /* | |
| 24 | ** The hook table at registry[&HOOKKEY] maps threads to their current | |
| 25 | ** hook function. (We only need the unique address of 'HOOKKEY'.) | |
| 26 | */ | |
| 27 | static const int HOOKKEY = 0; | |
| 21 | #define HOOKKEY "_HKEY" | |
| 28 | 22 | |
| 29 | 23 | |
| 24 | ||
| 30 | 25 | static int db_getregistry (lua_State *L) { |
| 31 | 26 | lua_pushvalue(L, LUA_REGISTRYINDEX); |
| 32 | 27 | return 1; |
| r242899 | r242900 | |
| 62 | 57 | |
| 63 | 58 | |
| 64 | 59 | static int db_setuservalue (lua_State *L) { |
| 60 | if (lua_type(L, 1) == LUA_TLIGHTUSERDATA) | |
| 61 | luaL_argerror(L, 1, "full userdata expected, got light userdata"); | |
| 65 | 62 | luaL_checktype(L, 1, LUA_TUSERDATA); |
| 66 | luaL_checkany(L, 2); | |
| 63 | if (!lua_isnoneornil(L, 2)) | |
| 64 | luaL_checktype(L, 2, LUA_TTABLE); | |
| 67 | 65 | lua_settop(L, 2); |
| 68 | 66 | lua_setuservalue(L, 1); |
| 69 | 67 | return 1; |
| 70 | 68 | } |
| 71 | 69 | |
| 72 | 70 | |
| 73 | /* | |
| 74 | ** Auxiliary function used by several library functions: check for | |
| 75 | ** an optional thread as function's first argument and set 'arg' with | |
| 76 | ** 1 if this argument is present (so that functions can skip it to | |
| 77 | ** access their other arguments) | |
| 78 | */ | |
| 71 | static void settabss (lua_State *L, const char *i, const char *v) { | |
| 72 | lua_pushstring(L, v); | |
| 73 | lua_setfield(L, -2, i); | |
| 74 | } | |
| 75 | ||
| 76 | ||
| 77 | static void settabsi (lua_State *L, const char *i, int v) { | |
| 78 | lua_pushinteger(L, v); | |
| 79 | lua_setfield(L, -2, i); | |
| 80 | } | |
| 81 | ||
| 82 | ||
| 83 | static void settabsb (lua_State *L, const char *i, int v) { | |
| 84 | lua_pushboolean(L, v); | |
| 85 | lua_setfield(L, -2, i); | |
| 86 | } | |
| 87 | ||
| 88 | ||
| 79 | 89 | static lua_State *getthread (lua_State *L, int *arg) { |
| 80 | 90 | if (lua_isthread(L, 1)) { |
| 81 | 91 | *arg = 1; |
| r242899 | r242900 | |
| 83 | 93 | } |
| 84 | 94 | else { |
| 85 | 95 | *arg = 0; |
| 86 | return L; | |
| 96 | return L; | |
| 87 | 97 | } |
| 88 | 98 | } |
| 89 | 99 | |
| 90 | 100 | |
| 91 | /* | |
| 92 | ** Variations of 'lua_settable', used by 'db_getinfo' to put results | |
| 93 | ** from 'lua_getinfo' into result table. Key is always a string; | |
| 94 | ** value can be a string, an int, or a boolean. | |
| 95 | */ | |
| 96 | static void settabss (lua_State *L, const char *k, const char *v) { | |
| 97 | lua_pushstring(L, v); | |
| 98 | lua_setfield(L, -2, k); | |
| 99 | } | |
| 100 | ||
| 101 | static void settabsi (lua_State *L, const char *k, int v) { | |
| 102 | lua_pushinteger(L, v); | |
| 103 | lua_setfield(L, -2, k); | |
| 104 | } | |
| 105 | ||
| 106 | static void settabsb (lua_State *L, const char *k, int v) { | |
| 107 | lua_pushboolean(L, v); | |
| 108 | lua_setfield(L, -2, k); | |
| 109 | } | |
| 110 | ||
| 111 | ||
| 112 | /* | |
| 113 | ** In function 'db_getinfo', the call to 'lua_getinfo' may push | |
| 114 | ** results on the stack; later it creates the result table to put | |
| 115 | ** these objects. Function 'treatstackoption' puts the result from | |
| 116 | ** 'lua_getinfo' on top of the result table so that it can call | |
| 117 | ** 'lua_setfield'. | |
| 118 | */ | |
| 119 | 101 | static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { |
| 120 | if (L == L1) | |
| 121 | lua_rotate(L, -2, 1); /* exchange object and table */ | |
| 102 | if (L == L1) { | |
| 103 | lua_pushvalue(L, -2); | |
| 104 | lua_remove(L, -3); | |
| 105 | } | |
| 122 | 106 | else |
| 123 | lua_xmove(L1, L, 1); /* move object to the "main" stack */ | |
| 124 | lua_setfield(L, -2, fname); /* put object into table */ | |
| 107 | lua_xmove(L1, L, 1); | |
| 108 | lua_setfield(L, -2, fname); | |
| 125 | 109 | } |
| 126 | 110 | |
| 127 | 111 | |
| 128 | /* | |
| 129 | ** Calls 'lua_getinfo' and collects all results in a new table. | |
| 130 | */ | |
| 131 | 112 | static int db_getinfo (lua_State *L) { |
| 132 | 113 | lua_Debug ar; |
| 133 | 114 | int arg; |
| 134 | 115 | lua_State *L1 = getthread(L, &arg); |
| 135 | 116 | const char *options = luaL_optstring(L, arg+2, "flnStu"); |
| 136 | if (lua_isfunction(L, arg + 1)) { /* info about a function? */ | |
| 137 | options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */ | |
| 138 | lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */ | |
| 139 | lua_xmove(L, L1, 1); | |
| 140 | } | |
| 141 | else { /* stack level */ | |
| 142 | if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { | |
| 117 | if (lua_isnumber(L, arg+1)) { | |
| 118 | if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { | |
| 143 | 119 | lua_pushnil(L); /* level out of range */ |
| 144 | 120 | return 1; |
| 145 | 121 | } |
| 146 | 122 | } |
| 123 | else if (lua_isfunction(L, arg+1)) { | |
| 124 | lua_pushfstring(L, ">%s", options); | |
| 125 | options = lua_tostring(L, -1); | |
| 126 | lua_pushvalue(L, arg+1); | |
| 127 | lua_xmove(L, L1, 1); | |
| 128 | } | |
| 129 | else | |
| 130 | return luaL_argerror(L, arg+1, "function or level expected"); | |
| 147 | 131 | if (!lua_getinfo(L1, options, &ar)) |
| 148 | 132 | return luaL_argerror(L, arg+2, "invalid option"); |
| 149 | lua_ | |
| 133 | lua_createtable(L, 0, 2); | |
| 150 | 134 | if (strchr(options, 'S')) { |
| 151 | 135 | settabss(L, "source", ar.source); |
| 152 | 136 | settabss(L, "short_src", ar.short_src); |
| r242899 | r242900 | |
| 180 | 164 | lua_State *L1 = getthread(L, &arg); |
| 181 | 165 | lua_Debug ar; |
| 182 | 166 | const char *name; |
| 183 | int nvar = | |
| 167 | int nvar = luaL_checkint(L, arg+2); /* local-variable index */ | |
| 184 | 168 | if (lua_isfunction(L, arg + 1)) { /* function argument? */ |
| 185 | 169 | lua_pushvalue(L, arg + 1); /* push function */ |
| 186 | 170 | lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ |
| 187 | return 1; | |
| 171 | return 1; | |
| 188 | 172 | } |
| 189 | 173 | else { /* stack-level argument */ |
| 190 | int level = (int)luaL_checkinteger(L, arg + 1); | |
| 191 | if (!lua_getstack(L1, level, &ar)) /* out of range? */ | |
| 174 | if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ | |
| 192 | 175 | return luaL_argerror(L, arg+1, "level out of range"); |
| 193 | 176 | name = lua_getlocal(L1, &ar, nvar); |
| 194 | 177 | if (name) { |
| 195 | lua_xmove(L1, L, 1); /* | |
| 178 | lua_xmove(L1, L, 1); /* push local value */ | |
| 196 | 179 | lua_pushstring(L, name); /* push name */ |
| 197 | lua_ | |
| 180 | lua_pushvalue(L, -2); /* re-order */ | |
| 198 | 181 | return 2; |
| 199 | 182 | } |
| 200 | 183 | else { |
| r242899 | r242900 | |
| 207 | 190 | |
| 208 | 191 | static int db_setlocal (lua_State *L) { |
| 209 | 192 | int arg; |
| 210 | const char *name; | |
| 211 | 193 | lua_State *L1 = getthread(L, &arg); |
| 212 | 194 | lua_Debug ar; |
| 213 | int level = (int)luaL_checkinteger(L, arg + 1); | |
| 214 | int nvar = (int)luaL_checkinteger(L, arg + 2); | |
| 215 | if (!lua_getstack(L1, level, &ar)) /* out of range? */ | |
| 195 | if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ | |
| 216 | 196 | return luaL_argerror(L, arg+1, "level out of range"); |
| 217 | 197 | luaL_checkany(L, arg+3); |
| 218 | 198 | lua_settop(L, arg+3); |
| 219 | 199 | lua_xmove(L, L1, 1); |
| 220 | name = lua_setlocal(L1, &ar, nvar); | |
| 221 | if (name == NULL) | |
| 222 | lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */ | |
| 223 | lua_pushstring(L, name); | |
| 200 | lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); | |
| 224 | 201 | return 1; |
| 225 | 202 | } |
| 226 | 203 | |
| 227 | 204 | |
| 228 | /* | |
| 229 | ** get (if 'get' is true) or set an upvalue from a closure | |
| 230 | */ | |
| 231 | 205 | static int auxupvalue (lua_State *L, int get) { |
| 232 | 206 | const char *name; |
| 233 | int n = (int)luaL_checkinteger(L, 2); /* upvalue index */ | |
| 234 | luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */ | |
| 207 | int n = luaL_checkint(L, 2); | |
| 208 | luaL_checktype(L, 1, LUA_TFUNCTION); | |
| 235 | 209 | name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); |
| 236 | 210 | if (name == NULL) return 0; |
| 237 | 211 | lua_pushstring(L, name); |
| 238 | lua_insert(L, -(get+1)); | |
| 212 | lua_insert(L, -(get+1)); | |
| 239 | 213 | return get + 1; |
| 240 | 214 | } |
| 241 | 215 | |
| r242899 | r242900 | |
| 251 | 225 | } |
| 252 | 226 | |
| 253 | 227 | |
| 254 | /* | |
| 255 | ** Check whether a given upvalue from a given closure exists and | |
| 256 | ** returns its index | |
| 257 | */ | |
| 258 | 228 | static int checkupval (lua_State *L, int argf, int argnup) { |
| 259 | int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ | |
| 260 | luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ | |
| 261 | luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup, | |
| 262 | "invalid upvalue index"); | |
| 229 | lua_Debug ar; | |
| 230 | int nup = luaL_checkint(L, argnup); | |
| 231 | luaL_checktype(L, argf, LUA_TFUNCTION); | |
| 232 | lua_pushvalue(L, argf); | |
| 233 | lua_getinfo(L, ">u", &ar); | |
| 234 | luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index"); | |
| 263 | 235 | return nup; |
| 264 | 236 | } |
| 265 | 237 | |
| r242899 | r242900 | |
| 281 | 253 | } |
| 282 | 254 | |
| 283 | 255 | |
| 284 | /* | |
| 285 | ** Call hook function registered at hook table for the current | |
| 286 | ** thread (if there is one) | |
| 287 | */ | |
| 256 | #define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY) | |
| 257 | ||
| 258 | ||
| 288 | 259 | static void hookf (lua_State *L, lua_Debug *ar) { |
| 289 | 260 | static const char *const hooknames[] = |
| 290 | 261 | {"call", "return", "line", "count", "tail call"}; |
| 291 | | |
| 262 | gethooktable(L); | |
| 292 | 263 | lua_pushthread(L); |
| 293 | if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ | |
| 294 | lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ | |
| 264 | lua_rawget(L, -2); | |
| 265 | if (lua_isfunction(L, -1)) { | |
| 266 | lua_pushstring(L, hooknames[(int)ar->event]); | |
| 295 | 267 | if (ar->currentline >= 0) |
| 296 | lua_pushinteger(L, ar->currentline); | |
| 268 | lua_pushinteger(L, ar->currentline); | |
| 297 | 269 | else lua_pushnil(L); |
| 298 | 270 | lua_assert(lua_getinfo(L, "lS", ar)); |
| 299 | lua_call(L, 2, 0); | |
| 271 | lua_call(L, 2, 0); | |
| 300 | 272 | } |
| 301 | 273 | } |
| 302 | 274 | |
| 303 | 275 | |
| 304 | /* | |
| 305 | ** Convert a string mask (for 'sethook') into a bit mask | |
| 306 | */ | |
| 307 | 276 | static int makemask (const char *smask, int count) { |
| 308 | 277 | int mask = 0; |
| 309 | 278 | if (strchr(smask, 'c')) mask |= LUA_MASKCALL; |
| r242899 | r242900 | |
| 314 | 283 | } |
| 315 | 284 | |
| 316 | 285 | |
| 317 | /* | |
| 318 | ** Convert a bit mask (for 'gethook') into a string mask | |
| 319 | */ | |
| 320 | 286 | static char *unmakemask (int mask, char *smask) { |
| 321 | 287 | int i = 0; |
| 322 | 288 | if (mask & LUA_MASKCALL) smask[i++] = 'c'; |
| r242899 | r242900 | |
| 331 | 297 | int arg, mask, count; |
| 332 | 298 | lua_Hook func; |
| 333 | 299 | lua_State *L1 = getthread(L, &arg); |
| 334 | if (lua_isnoneornil(L, arg+1)) { | |
| 300 | if (lua_isnoneornil(L, arg+1)) { | |
| 335 | 301 | lua_settop(L, arg+1); |
| 336 | 302 | func = NULL; mask = 0; count = 0; /* turn off hooks */ |
| 337 | 303 | } |
| 338 | 304 | else { |
| 339 | 305 | const char *smask = luaL_checkstring(L, arg+2); |
| 340 | 306 | luaL_checktype(L, arg+1, LUA_TFUNCTION); |
| 341 | count = | |
| 307 | count = luaL_optint(L, arg+3, 0); | |
| 342 | 308 | func = hookf; mask = makemask(smask, count); |
| 343 | 309 | } |
| 344 | if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) { | |
| 345 | lua_createtable(L, 0, 2); /* create a hook table */ | |
| 346 | lua_pushvalue(L, -1); | |
| 347 | lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY); /* set it in position */ | |
| 310 | if (gethooktable(L) == 0) { /* creating hook table? */ | |
| 348 | 311 | lua_pushstring(L, "k"); |
| 349 | 312 | lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ |
| 350 | 313 | lua_pushvalue(L, -1); |
| 351 | 314 | lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ |
| 352 | 315 | } |
| 353 | lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ | |
| 354 | lua_pushvalue(L, arg + 1); /* value (hook function) */ | |
| 355 | lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */ | |
| 356 | lua_sethook(L1, func, mask, count); | |
| 316 | lua_pushthread(L1); lua_xmove(L1, L, 1); | |
| 317 | lua_pushvalue(L, arg+1); | |
| 318 | lua_rawset(L, -3); /* set new hook */ | |
| 319 | lua_sethook(L1, func, mask, count); /* set hooks */ | |
| 357 | 320 | return 0; |
| 358 | 321 | } |
| 359 | 322 | |
| r242899 | r242900 | |
| 364 | 327 | char buff[5]; |
| 365 | 328 | int mask = lua_gethookmask(L1); |
| 366 | 329 | lua_Hook hook = lua_gethook(L1); |
| 367 | if (hook == NULL) /* no hook? */ | |
| 368 | lua_pushnil(L); | |
| 369 | else if (hook != hookf) /* external hook? */ | |
| 330 | if (hook != NULL && hook != hookf) /* external hook? */ | |
| 370 | 331 | lua_pushliteral(L, "external hook"); |
| 371 | else { /* hook table must exist */ | |
| 372 | lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); | |
| 332 | else { | |
| 333 | gethooktable(L); | |
| 373 | 334 | lua_pushthread(L1); lua_xmove(L1, L, 1); |
| 374 | lua_rawget(L, -2); /* | |
| 335 | lua_rawget(L, -2); /* get hook */ | |
| 375 | 336 | lua_remove(L, -2); /* remove hook table */ |
| 376 | 337 | } |
| 377 | lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */ | |
| 378 | lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */ | |
| 338 | lua_pushstring(L, unmakemask(mask, buff)); | |
| 339 | lua_pushinteger(L, lua_gethookcount(L1)); | |
| 379 | 340 | return 3; |
| 380 | 341 | } |
| 381 | 342 | |
| r242899 | r242900 | |
| 383 | 344 | static int db_debug (lua_State *L) { |
| 384 | 345 | for (;;) { |
| 385 | 346 | char buffer[250]; |
| 386 | lua_writestringerror("%s", "lua_debug> "); | |
| 347 | luai_writestringerror("%s", "lua_debug> "); | |
| 387 | 348 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || |
| 388 | 349 | strcmp(buffer, "cont\n") == 0) |
| 389 | 350 | return 0; |
| 390 | 351 | if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || |
| 391 | 352 | lua_pcall(L, 0, 0, 0)) |
| 392 | lua_writestringerror("%s\n", lua_tostring(L, -1)); | |
| 353 | luai_writestringerror("%s\n", lua_tostring(L, -1)); | |
| 393 | 354 | lua_settop(L, 0); /* remove eventual returns */ |
| 394 | 355 | } |
| 395 | 356 | } |
| r242899 | r242900 | |
| 402 | 363 | if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ |
| 403 | 364 | lua_pushvalue(L, arg + 1); /* return it untouched */ |
| 404 | 365 | else { |
| 405 | int level = | |
| 366 | int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0); | |
| 406 | 367 | luaL_traceback(L, L1, msg, level); |
| 407 | 368 | } |
| 408 | 369 | return 1; |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2. | |
| 2 | ** $Id: ldebug.c,v 2.90.1.3 2013/05/16 16:04:15 roberto Exp $ | |
| 3 | 3 | ** Debug Interface |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define ldebug_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <stdarg.h> |
| 14 | 9 | #include <stddef.h> |
| 15 | 10 | #include <string.h> |
| 16 | 11 | |
| 12 | ||
| 13 | #define ldebug_c | |
| 14 | #define LUA_CORE | |
| 15 | ||
| 17 | 16 | #include "lua.h" |
| 18 | 17 | |
| 19 | 18 | #include "lapi.h" |
| r242899 | r242900 | |
| 51 | 50 | /* |
| 52 | 51 | ** this function can be called asynchronous (e.g. during a signal) |
| 53 | 52 | */ |
| 54 | LUA_API | |
| 53 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { | |
| 55 | 54 | if (func == NULL || mask == 0) { /* turn off hooks? */ |
| 56 | 55 | mask = 0; |
| 57 | 56 | func = NULL; |
| r242899 | r242900 | |
| 62 | 61 | L->basehookcount = count; |
| 63 | 62 | resethookcount(L); |
| 64 | 63 | L->hookmask = cast_byte(mask); |
| 64 | return 1; | |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | |
| r242899 | r242900 | |
| 167 | 167 | StkId pos = 0; /* to avoid warnings */ |
| 168 | 168 | const char *name = findlocal(L, ar->i_ci, n, &pos); |
| 169 | 169 | lua_lock(L); |
| 170 | if (name) | |
| 170 | if (name) | |
| 171 | 171 | setobjs2s(L, pos, L->top - 1); |
| 172 | L->top--; /* pop value */ | |
| 173 | } | |
| 172 | L->top--; /* pop value */ | |
| 174 | 173 | lua_unlock(L); |
| 175 | 174 | return name; |
| 176 | 175 | } |
| r242899 | r242900 | |
| 273 | 272 | if (*what == '>') { |
| 274 | 273 | ci = NULL; |
| 275 | 274 | func = L->top - 1; |
| 276 | api_check(ttisfunction(func), "function expected"); | |
| 275 | api_check(L, ttisfunction(func), "function expected"); | |
| 277 | 276 | what++; /* skip the '>' */ |
| 278 | 277 | L->top--; /* pop function */ |
| 279 | 278 | } |
| r242899 | r242900 | |
| 367 | 366 | case OP_JMP: { |
| 368 | 367 | int b = GETARG_sBx(i); |
| 369 | 368 | int dest = pc + 1 + b; |
| 370 | /* jump is forward and do not skip | |
| 369 | /* jump is forward and do not skip `lastpc'? */ | |
| 371 | 370 | if (pc < dest && dest <= lastpc) { |
| 372 | 371 | if (dest > jmptarget) |
| 373 | 372 | jmptarget = dest; /* update 'jmptarget' */ |
| 374 | 373 | } |
| 375 | 374 | break; |
| 376 | 375 | } |
| 376 | case OP_TEST: { | |
| 377 | if (reg == a) /* jumped code can change 'a' */ | |
| 378 | setreg = filterpc(pc, jmptarget); | |
| 379 | break; | |
| 380 | } | |
| 377 | 381 | default: |
| 378 | 382 | if (testAMode(op) && reg == a) /* any instruction that set A */ |
| 379 | 383 | setreg = filterpc(pc, jmptarget); |
| r242899 | r242900 | |
| 439 | 443 | |
| 440 | 444 | |
| 441 | 445 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { |
| 442 | TMS tm | |
| 446 | TMS tm; | |
| 443 | 447 | Proto *p = ci_func(ci)->p; /* calling function */ |
| 444 | 448 | int pc = currentpc(ci); /* calling instruction index */ |
| 445 | 449 | Instruction i = p->code[pc]; /* calling instruction */ |
| 446 | if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ | |
| 447 | *name = "?"; | |
| 448 | return "hook"; | |
| 449 | } | |
| 450 | 450 | switch (GET_OPCODE(i)) { |
| 451 | 451 | case OP_CALL: |
| 452 | 452 | case OP_TAILCALL: /* get function name */ |
| r242899 | r242900 | |
| 456 | 456 | return "for iterator"; |
| 457 | 457 | } |
| 458 | 458 | /* all other instructions can call only through metamethods */ |
| 459 | case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: | |
| 460 | tm = TM_INDEX; | |
| 461 | break; | |
| 462 | case OP_SETTABUP: case OP_SETTABLE: | |
| 463 | tm = TM_NEWINDEX; | |
| 464 | break; | |
| 465 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: | |
| 466 | case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: | |
| 467 | case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { | |
| 468 | int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD); /* ORDER OP */ | |
| 469 | tm = cast(TMS, offset + cast_int(TM_ADD)); /* ORDER TM */ | |
| 470 | break; | |
| 471 | } | |
| 459 | case OP_SELF: | |
| 460 | case OP_GETTABUP: | |
| 461 | case OP_GETTABLE: tm = TM_INDEX; break; | |
| 462 | case OP_SETTABUP: | |
| 463 | case OP_SETTABLE: tm = TM_NEWINDEX; break; | |
| 464 | case OP_EQ: tm = TM_EQ; break; | |
| 465 | case OP_ADD: tm = TM_ADD; break; | |
| 466 | case OP_SUB: tm = TM_SUB; break; | |
| 467 | case OP_MUL: tm = TM_MUL; break; | |
| 468 | case OP_DIV: tm = TM_DIV; break; | |
| 469 | case OP_MOD: tm = TM_MOD; break; | |
| 470 | case OP_POW: tm = TM_POW; break; | |
| 472 | 471 | case OP_UNM: tm = TM_UNM; break; |
| 473 | case OP_BNOT: tm = TM_BNOT; break; | |
| 474 | 472 | case OP_LEN: tm = TM_LEN; break; |
| 475 | case OP_CONCAT: tm = TM_CONCAT; break; | |
| 476 | case OP_EQ: tm = TM_EQ; break; | |
| 477 | 473 | case OP_LT: tm = TM_LT; break; |
| 478 | 474 | case OP_LE: tm = TM_LE; break; |
| 479 | default: lua_assert(0); /* other instructions cannot call a function */ | |
| 475 | case OP_CONCAT: tm = TM_CONCAT; break; | |
| 476 | default: | |
| 477 | return NULL; /* else no useful name can be found */ | |
| 480 | 478 | } |
| 481 | 479 | *name = getstr(G(L)->tmname[tm]); |
| 482 | 480 | return "metamethod"; |
| r242899 | r242900 | |
| 487 | 485 | |
| 488 | 486 | |
| 489 | 487 | /* |
| 490 | ** The subtraction of two potentially unrelated pointers is | |
| 491 | ** not ISO C, but it should not crash a program; the subsequent | |
| 492 | ** checks are ISO C and ensure a correct result. | |
| 488 | ** only ANSI way to check whether a pointer points to an array | |
| 489 | ** (used only for error messages, so efficiency is not a big concern) | |
| 493 | 490 | */ |
| 494 | 491 | static int isinstack (CallInfo *ci, const TValue *o) { |
| 495 | ptrdiff_t i = o - ci->u.l.base; | |
| 496 | return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o); | |
| 492 | StkId p; | |
| 493 | for (p = ci->u.l.base; p < ci->top; p++) | |
| 494 | if (o == p) return 1; | |
| 495 | return 0; | |
| 497 | 496 | } |
| 498 | 497 | |
| 499 | 498 | |
| 500 | /* | |
| 501 | ** Checks whether value 'o' came from an upvalue. (That can only happen | |
| 502 | ** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on | |
| 503 | ** upvalues.) | |
| 504 | */ | |
| 505 | 499 | static const char *getupvalname (CallInfo *ci, const TValue *o, |
| 506 | 500 | const char **name) { |
| 507 | 501 | LClosure *c = ci_func(ci); |
| r242899 | r242900 | |
| 516 | 510 | } |
| 517 | 511 | |
| 518 | 512 | |
| 519 | static const char *varinfo (lua_State *L, const TValue *o) { | |
| 520 | const char *name = NULL; /* to avoid warnings */ | |
| 513 | l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { | |
| 521 | 514 | CallInfo *ci = L->ci; |
| 515 | const char *name = NULL; | |
| 516 | const char *t = objtypename(o); | |
| 522 | 517 | const char *kind = NULL; |
| 523 | 518 | if (isLua(ci)) { |
| 524 | 519 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ |
| r242899 | r242900 | |
| 526 | 521 | kind = getobjname(ci_func(ci)->p, currentpc(ci), |
| 527 | 522 | cast_int(o - ci->u.l.base), &name); |
| 528 | 523 | } |
| 529 | return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; | |
| 524 | if (kind) | |
| 525 | luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", | |
| 526 | op, kind, name, t); | |
| 527 | else | |
| 528 | luaG_runerror(L, "attempt to %s a %s value", op, t); | |
| 530 | 529 | } |
| 531 | 530 | |
| 532 | 531 | |
| 533 | l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { | |
| 534 | const char *t = objtypename(o); | |
| 535 | luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o)); | |
| 536 | } | |
| 537 | ||
| 538 | ||
| 539 | l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { | |
| 540 | if (ttisstring(p1) || cvt2str(p1)) p1 = p2; | |
| 532 | l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) { | |
| 533 | if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; | |
| 534 | lua_assert(!ttisstring(p1) && !ttisnumber(p1)); | |
| 541 | 535 | luaG_typeerror(L, p1, "concatenate"); |
| 542 | 536 | } |
| 543 | 537 | |
| 544 | 538 | |
| 545 | l_noret luaG_opinterror (lua_State *L, const TValue *p1, | |
| 546 | const TValue *p2, const char *msg) { | |
| 547 | lua_Number temp; | |
| 548 | if (!tonumber(p1, &temp)) /* first operand is wrong? */ | |
| 549 | p2 = p1; /* now second is wrong */ | |
| 550 | luaG_typeerror(L, p2, msg); | |
| 539 | l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { | |
| 540 | TValue temp; | |
| 541 | if (luaV_tonumber(p1, &temp) == NULL) | |
| 542 | p2 = p1; /* first operand is wrong */ | |
| 543 | luaG_typeerror(L, p2, "perform arithmetic on"); | |
| 551 | 544 | } |
| 552 | 545 | |
| 553 | 546 | |
| 554 | /* | |
| 555 | ** Error when both values are convertible to numbers, but not to integers | |
| 556 | */ | |
| 557 | l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { | |
| 558 | lua_Integer temp; | |
| 559 | if (!tointeger(p1, &temp)) | |
| 560 | p2 = p1; | |
| 561 | luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); | |
| 562 | } | |
| 563 | ||
| 564 | ||
| 565 | 547 | l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { |
| 566 | 548 | const char *t1 = objtypename(p1); |
| 567 | 549 | const char *t2 = objtypename(p2); |
| r242899 | r242900 | |
| 591 | 573 | l_noret luaG_errormsg (lua_State *L) { |
| 592 | 574 | if (L->errfunc != 0) { /* is there an error handling function? */ |
| 593 | 575 | StkId errfunc = restorestack(L, L->errfunc); |
| 576 | if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); | |
| 594 | 577 | setobjs2s(L, L->top, L->top - 1); /* move argument */ |
| 595 | 578 | setobjs2s(L, L->top - 1, errfunc); /* push function */ |
| 596 | L->top++; | |
| 579 | L->top++; | |
| 597 | 580 | luaD_call(L, L->top - 2, 1, 0); /* call it */ |
| 598 | 581 | } |
| 599 | 582 | luaD_throw(L, LUA_ERRRUN); |
| r242899 | r242900 | |
| 608 | 591 | luaG_errormsg(L); |
| 609 | 592 | } |
| 610 | 593 | |
| 611 | ||
| 612 | void luaG_traceexec (lua_State *L) { | |
| 613 | CallInfo *ci = L->ci; | |
| 614 | lu_byte mask = L->hookmask; | |
| 615 | int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); | |
| 616 | if (counthook) | |
| 617 | resethookcount(L); /* reset count */ | |
| 618 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ | |
| 619 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ | |
| 620 | return; /* do not call hook again (VM yielded, so it did not move) */ | |
| 621 | } | |
| 622 | if (counthook) | |
| 623 | luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ | |
| 624 | if (mask & LUA_MASKLINE) { | |
| 625 | Proto *p = ci_func(ci)->p; | |
| 626 | int npc = pcRel(ci->u.l.savedpc, p); | |
| 627 | int newline = getfuncline(p, npc); | |
| 628 | if (npc == 0 || /* call linehook when enter a new function, */ | |
| 629 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ | |
| 630 | newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ | |
| 631 | luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ | |
| 632 | } | |
| 633 | L->oldpc = ci->u.l.savedpc; | |
| 634 | if (L->status == LUA_YIELD) { /* did hook yield? */ | |
| 635 | if (counthook) | |
| 636 | L->hookcount = 1; /* undo decrement to zero */ | |
| 637 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ | |
| 638 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ | |
| 639 | ci->func = L->top - 1; /* protect stack below results */ | |
| 640 | luaD_throw(L, LUA_YIELD); | |
| 641 | } | |
| 642 | } | |
| 643 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ldebug.h,v 2.1 | |
| 2 | ** $Id: ldebug.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 13 | 13 | |
| 14 | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) |
| 15 | 15 | |
| 16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : | |
| 16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) | |
| 17 | 17 | |
| 18 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) |
| 19 | 19 | |
| r242899 | r242900 | |
| 23 | 23 | |
| 24 | 24 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, |
| 25 | 25 | const char *opname); |
| 26 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, | |
| 27 | const TValue *p2); | |
| 28 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, | |
| 29 | const TValue *p2, | |
| 30 | const char *msg); | |
| 31 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, | |
| 26 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2); | |
| 27 | LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1, | |
| 32 | 28 | const TValue *p2); |
| 33 | 29 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, |
| 34 | 30 | const TValue *p2); |
| 35 | 31 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); |
| 36 | 32 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); |
| 37 | LUAI_FUNC void luaG_traceexec (lua_State *L); | |
| 38 | 33 | |
| 39 | ||
| 40 | 34 | #endif |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.13 | |
| 2 | ** $Id: ldo.c,v 2.108.1.3 2013/11/08 18:22:50 roberto Exp $ | |
| 3 | 3 | ** Stack and Call structure of Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define ldo_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <setjmp.h> |
| 14 | 9 | #include <stdlib.h> |
| 15 | 10 | #include <string.h> |
| 16 | 11 | |
| 12 | #define ldo_c | |
| 13 | #define LUA_CORE | |
| 14 | ||
| 17 | 15 | #include "lua.h" |
| 18 | 16 | |
| 19 | 17 | #include "lapi.h" |
| r242899 | r242900 | |
| 35 | 33 | |
| 36 | 34 | |
| 37 | 35 | |
| 38 | #define errorstatus(s) ((s) > LUA_YIELD) | |
| 39 | 36 | |
| 40 | ||
| 41 | 37 | /* |
| 42 | 38 | ** {====================================================== |
| 43 | 39 | ** Error-recovery functions |
| r242899 | r242900 | |
| 50 | 46 | ** C++ code, with _longjmp/_setjmp when asked to use them, and with |
| 51 | 47 | ** longjmp/setjmp otherwise. |
| 52 | 48 | */ |
| 53 | #if !defined(LUAI_THROW) | |
| 49 | #if !defined(LUAI_THROW) | |
| 54 | 50 | |
| 55 | #if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */ | |
| 56 | ||
| 51 | #if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) | |
| 57 | 52 | /* C++ exceptions */ |
| 58 | 53 | #define LUAI_THROW(L,c) throw(c) |
| 59 | 54 | #define LUAI_TRY(L,c,a) \ |
| 60 | 55 | try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } |
| 61 | 56 | #define luai_jmpbuf int /* dummy variable */ |
| 62 | 57 | |
| 63 | #elif defined(LUA_USE_POSIX) /* }{ */ | |
| 64 | ||
| 65 | /* in POSIX, try _longjmp/_setjmp (more efficient) */ | |
| 58 | #elif defined(LUA_USE_ULONGJMP) | |
| 59 | /* in Unix, try _longjmp/_setjmp (more efficient) */ | |
| 66 | 60 | #define LUAI_THROW(L,c) _longjmp((c)->b, 1) |
| 67 | 61 | #define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } |
| 68 | 62 | #define luai_jmpbuf jmp_buf |
| 69 | 63 | |
| 70 | #else /* }{ */ | |
| 71 | ||
| 72 | /* ISO C handling with long jumps */ | |
| 64 | #else | |
| 65 | /* default handling with long jumps */ | |
| 73 | 66 | #define LUAI_THROW(L,c) longjmp((c)->b, 1) |
| 74 | 67 | #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } |
| 75 | 68 | #define luai_jmpbuf jmp_buf |
| 76 | 69 | |
| 77 | #endif | |
| 70 | #endif | |
| 78 | 71 | |
| 79 | #endif | |
| 72 | #endif | |
| 80 | 73 | |
| 81 | 74 | |
| 82 | 75 | |
| r242899 | r242900 | |
| 113 | 106 | LUAI_THROW(L, L->errorJmp); /* jump to it */ |
| 114 | 107 | } |
| 115 | 108 | else { /* thread has no error handler */ |
| 116 | global_State *g = G(L); | |
| 117 | 109 | L->status = cast_byte(errcode); /* mark it as dead */ |
| 118 | if (g->mainthread->errorJmp) { /* main thread has a handler? */ | |
| 119 | setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ | |
| 120 | luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ | |
| 110 | if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */ | |
| 111 | setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */ | |
| 112 | luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */ | |
| 121 | 113 | } |
| 122 | 114 | else { /* no handler at all; abort */ |
| 123 | if (g->panic) { /* panic function? */ | |
| 124 | seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ | |
| 125 | if (L->ci->top < L->top) | |
| 126 | L->ci->top = L->top; /* pushing msg. can break this invariant */ | |
| 115 | if (G(L)->panic) { /* panic function? */ | |
| 127 | 116 | lua_unlock(L); |
| 128 | | |
| 117 | G(L)->panic(L); /* call it (last chance to jump out) */ | |
| 129 | 118 | } |
| 130 | 119 | abort(); |
| 131 | 120 | } |
| r242899 | r242900 | |
| 152 | 141 | |
| 153 | 142 | static void correctstack (lua_State *L, TValue *oldstack) { |
| 154 | 143 | CallInfo *ci; |
| 155 | | |
| 144 | GCObject *up; | |
| 156 | 145 | L->top = (L->top - oldstack) + L->stack; |
| 157 | for (up = L->openupval; up != NULL; up = up->u.open.next) | |
| 158 | up->v = (up->v - oldstack) + L->stack; | |
| 146 | for (up = L->openupval; up != NULL; up = up->gch.next) | |
| 147 | gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; | |
| 159 | 148 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
| 160 | 149 | ci->top = (ci->top - oldstack) + L->stack; |
| 161 | 150 | ci->func = (ci->func - oldstack) + L->stack; |
| r242899 | r242900 | |
| 217 | 206 | int inuse = stackinuse(L); |
| 218 | 207 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; |
| 219 | 208 | if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; |
| 220 | if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */ | |
| 221 | luaE_freeCI(L); /* free all CIs (list grew because of an error) */ | |
| 222 | else | |
| 223 | luaE_shrinkCI(L); /* shrink list */ | |
| 224 | if (inuse > LUAI_MAXSTACK || /* still handling stack overflow? */ | |
| 209 | if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */ | |
| 225 | 210 | goodsize >= L->stacksize) /* would grow instead of shrink? */ |
| 226 | 211 | condmovestack(L); /* don't change stack (change only for debugging) */ |
| 227 | 212 | else |
| r242899 | r242900 | |
| 286 | 271 | } |
| 287 | 272 | |
| 288 | 273 | |
| 289 | /* | |
| 290 | ** Check whether __call metafield of 'func' is a function. If so, put | |
| 291 | ** it in stack below original 'func' so that 'luaD_precall' can call | |
| 292 | ** it. Raise an error if __call metafield is not a function. | |
| 293 | */ | |
| 294 | static void tryfuncTM (lua_State *L, StkId func) { | |
| 274 | static StkId tryfuncTM (lua_State *L, StkId func) { | |
| 295 | 275 | const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); |
| 296 | 276 | StkId p; |
| 277 | ptrdiff_t funcr = savestack(L, func); | |
| 297 | 278 | if (!ttisfunction(tm)) |
| 298 | 279 | luaG_typeerror(L, func, "call"); |
| 299 | /* Open a hole inside the stack at 'func' */ | |
| 300 | for (p = L->top; p > func; p--) | |
| 301 | setobjs2s(L, p, p-1); | |
| 302 | L->top++; /* slot ensured by caller */ | |
| 280 | /* Open a hole inside the stack at `func' */ | |
| 281 | for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); | |
| 282 | incr_top(L); | |
| 283 | func = restorestack(L, funcr); /* previous call may change stack */ | |
| 303 | 284 | setobj2s(L, func, tm); /* tag method is the new function to be called */ |
| 285 | return func; | |
| 304 | 286 | } |
| 305 | 287 | |
| 306 | 288 | |
| r242899 | r242900 | |
| 370 | 352 | return 0; |
| 371 | 353 | } |
| 372 | 354 | default: { /* not a function */ |
| 373 | luaD_checkstack(L, 1); /* ensure space for metamethod */ | |
| 374 | func = restorestack(L, funcr); /* previous call may change stack */ | |
| 375 | tryfuncTM(L, func); /* try to get '__call' metamethod */ | |
| 355 | func = tryfuncTM(L, func); /* retry with 'function' tag method */ | |
| 376 | 356 | return luaD_precall(L, func, nresults); /* now it must be a function */ |
| 377 | 357 | } |
| 378 | 358 | } |
| r242899 | r242900 | |
| 425 | 405 | } |
| 426 | 406 | |
| 427 | 407 | |
| 428 | /* | |
| 429 | ** Completes the execution of an interrupted C function, calling its | |
| 430 | ** continuation function. | |
| 431 | */ | |
| 432 | static void finishCcall (lua_State *L, int status) { | |
| 408 | static void finishCcall (lua_State *L) { | |
| 433 | 409 | CallInfo *ci = L->ci; |
| 434 | 410 | int n; |
| 435 | /* must have a continuation and must be able to call it */ | |
| 436 | lua_assert(ci->u.c.k != NULL && L->nny == 0); | |
| 437 | /* error status can only happen in a protected call */ | |
| 438 | lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); | |
| 411 | lua_assert(ci->u.c.k != NULL); /* must have a continuation */ | |
| 412 | lua_assert(L->nny == 0); | |
| 439 | 413 | if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ |
| 440 | 414 | ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */ |
| 441 | 415 | L->errfunc = ci->u.c.old_errfunc; |
| 442 | 416 | } |
| 443 | /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already | |
| 444 | handled */ | |
| 417 | /* finish 'lua_callk'/'lua_pcall' */ | |
| 445 | 418 | adjustresults(L, ci->nresults); |
| 446 | 419 | /* call continuation function */ |
| 420 | if (!(ci->callstatus & CIST_STAT)) /* no call status? */ | |
| 421 | ci->u.c.status = LUA_YIELD; /* 'default' status */ | |
| 422 | lua_assert(ci->u.c.status != LUA_OK); | |
| 423 | ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED; | |
| 447 | 424 | lua_unlock(L); |
| 448 | n = (*ci->u.c.k)(L | |
| 425 | n = (*ci->u.c.k)(L); | |
| 449 | 426 | lua_lock(L); |
| 450 | 427 | api_checknelems(L, n); |
| 451 | 428 | /* finish 'luaD_precall' */ |
| r242899 | r242900 | |
| 453 | 430 | } |
| 454 | 431 | |
| 455 | 432 | |
| 456 | /* | |
| 457 | ** Executes "full continuation" (everything in the stack) of a | |
| 458 | ** previously interrupted coroutine until the stack is empty (or another | |
| 459 | ** interruption long-jumps out of the loop). If the coroutine is | |
| 460 | ** recovering from an error, 'ud' points to the error status, which must | |
| 461 | ** be passed to the first continuation function (otherwise the default | |
| 462 | ** status is LUA_YIELD). | |
| 463 | */ | |
| 464 | 433 | static void unroll (lua_State *L, void *ud) { |
| 465 | if (ud != NULL) /* error status? */ | |
| 466 | finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ | |
| 467 | while (L->ci != &L->base_ci) { /* something in the stack */ | |
| 434 | UNUSED(ud); | |
| 435 | for (;;) { | |
| 436 | if (L->ci == &L->base_ci) /* stack is empty? */ | |
| 437 | return; /* coroutine finished normally */ | |
| 468 | 438 | if (!isLua(L->ci)) /* C function? */ |
| 469 | finishCcall(L | |
| 439 | finishCcall(L); | |
| 470 | 440 | else { /* Lua function */ |
| 471 | 441 | luaV_finishOp(L); /* finish interrupted instruction */ |
| 472 | 442 | luaV_execute(L); /* execute down to higher C 'boundary' */ |
| r242899 | r242900 | |
| 476 | 446 | |
| 477 | 447 | |
| 478 | 448 | /* |
| 479 | ** Try to find a suspended protected call (a "recover point") for the | |
| 480 | ** given thread. | |
| 449 | ** check whether thread has a suspended protected call | |
| 481 | 450 | */ |
| 482 | 451 | static CallInfo *findpcall (lua_State *L) { |
| 483 | 452 | CallInfo *ci; |
| r242899 | r242900 | |
| 489 | 458 | } |
| 490 | 459 | |
| 491 | 460 | |
| 492 | /* | |
| 493 | ** Recovers from an error in a coroutine. Finds a recover point (if | |
| 494 | ** there is one) and completes the execution of the interrupted | |
| 495 | ** 'luaD_pcall'. If there is no recover point, returns zero. | |
| 496 | */ | |
| 497 | 461 | static int recover (lua_State *L, int status) { |
| 498 | 462 | StkId oldtop; |
| 499 | 463 | CallInfo *ci = findpcall(L); |
| r242899 | r242900 | |
| 503 | 467 | luaF_close(L, oldtop); |
| 504 | 468 | seterrorobj(L, status, oldtop); |
| 505 | 469 | L->ci = ci; |
| 506 | L->allowhook = | |
| 470 | L->allowhook = ci->u.c.old_allowhook; | |
| 507 | 471 | L->nny = 0; /* should be zero to be yieldable */ |
| 508 | 472 | luaD_shrinkstack(L); |
| 509 | 473 | L->errfunc = ci->u.c.old_errfunc; |
| 474 | ci->callstatus |= CIST_STAT; /* call has error status */ | |
| 475 | ci->u.c.status = status; /* (here it is) */ | |
| 510 | 476 | return 1; /* continue running the coroutine */ |
| 511 | 477 | } |
| 512 | 478 | |
| r242899 | r242900 | |
| 525 | 491 | |
| 526 | 492 | |
| 527 | 493 | /* |
| 528 | ** Do the work for 'lua_resume' in protected mode. Most of the work | |
| 529 | ** depends on the status of the coroutine: initial state, suspended | |
| 530 | ** inside a hook, or regularly suspended (optionally with a continuation | |
| 531 | ** function), plus erroneous cases: non-suspended coroutine or dead | |
| 532 | ** coroutine. | |
| 494 | ** do the work for 'lua_resume' in protected mode | |
| 533 | 495 | */ |
| 534 | 496 | static void resume (lua_State *L, void *ud) { |
| 535 | 497 | int nCcalls = L->nCcalls; |
| r242899 | r242900 | |
| 547 | 509 | else if (L->status != LUA_YIELD) |
| 548 | 510 | resume_error(L, "cannot resume dead coroutine", firstArg); |
| 549 | 511 | else { /* resuming from previous yield */ |
| 550 | L->status = LUA_OK; | |
| 512 | L->status = LUA_OK; | |
| 551 | 513 | ci->func = restorestack(L, ci->extra); |
| 552 | 514 | if (isLua(ci)) /* yielded inside a hook? */ |
| 553 | 515 | luaV_execute(L); /* just continue running Lua code */ |
| 554 | 516 | else { /* 'common' yield */ |
| 555 | if (ci->u.c.k != NULL) { /* does it have a continuation | |
| 517 | if (ci->u.c.k != NULL) { /* does it have a continuation? */ | |
| 556 | 518 | int n; |
| 519 | ci->u.c.status = LUA_YIELD; /* 'default' status */ | |
| 520 | ci->callstatus |= CIST_YIELDED; | |
| 557 | 521 | lua_unlock(L); |
| 558 | n = (*ci->u.c.k)(L | |
| 522 | n = (*ci->u.c.k)(L); /* call continuation */ | |
| 559 | 523 | lua_lock(L); |
| 560 | 524 | api_checknelems(L, n); |
| 561 | 525 | firstArg = L->top - n; /* yield results come from continuation */ |
| 562 | 526 | } |
| 563 | 527 | luaD_poscall(L, firstArg); /* finish 'luaD_precall' */ |
| 564 | 528 | } |
| 565 | unroll(L, NULL); | |
| 529 | unroll(L, NULL); | |
| 566 | 530 | } |
| 567 | 531 | lua_assert(nCcalls == L->nCcalls); |
| 568 | 532 | } |
| r242899 | r242900 | |
| 570 | 534 | |
| 571 | 535 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { |
| 572 | 536 | int status; |
| 573 | int oldnny = L->nny; /* save | |
| 537 | int oldnny = L->nny; /* save 'nny' */ | |
| 574 | 538 | lua_lock(L); |
| 575 | 539 | luai_userstateresume(L, nargs); |
| 576 | 540 | L->nCcalls = (from) ? from->nCcalls + 1 : 1; |
| r242899 | r242900 | |
| 579 | 543 | status = luaD_rawrunprotected(L, resume, L->top - nargs); |
| 580 | 544 | if (status == -1) /* error calling 'lua_resume'? */ |
| 581 | 545 | status = LUA_ERRRUN; |
| 582 | else { /* continue running after recoverable errors */ | |
| 583 | while (errorstatus(status) && recover(L, status)) { | |
| 584 | /* unroll continuation */ | |
| 585 | status = luaD_rawrunprotected(L, unroll, &status); | |
| 546 | else { /* yield or regular error */ | |
| 547 | while (status != LUA_OK && status != LUA_YIELD) { /* error? */ | |
| 548 | if (recover(L, status)) /* recover point? */ | |
| 549 | status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */ | |
| 550 | else { /* unrecoverable error */ | |
| 551 | L->status = cast_byte(status); /* mark thread as `dead' */ | |
| 552 | seterrorobj(L, status, L->top); | |
| 553 | L->ci->top = L->top; | |
| 554 | break; | |
| 555 | } | |
| 586 | 556 | } |
| 587 | if (errorstatus(status)) { /* unrecoverable error? */ | |
| 588 | L->status = cast_byte(status); /* mark thread as 'dead' */ | |
| 589 | seterrorobj(L, status, L->top); /* push error message */ | |
| 590 | L->ci->top = L->top; | |
| 591 | } | |
| 592 | else lua_assert(status == L->status); /* normal end or yield */ | |
| 557 | lua_assert(status == L->status); | |
| 593 | 558 | } |
| 594 | 559 | L->nny = oldnny; /* restore 'nny' */ |
| 595 | 560 | L->nCcalls--; |
| r242899 | r242900 | |
| 599 | 564 | } |
| 600 | 565 | |
| 601 | 566 | |
| 602 | LUA_API int lua_isyieldable (lua_State *L) { | |
| 603 | return (L->nny == 0); | |
| 604 | } | |
| 605 | ||
| 606 | ||
| 607 | LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |
| 608 | lua_KFunction k) { | |
| 567 | LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) { | |
| 609 | 568 | CallInfo *ci = L->ci; |
| 610 | 569 | luai_userstateyield(L, nresults); |
| 611 | 570 | lua_lock(L); |
| r242899 | r242900 | |
| 619 | 578 | L->status = LUA_YIELD; |
| 620 | 579 | ci->extra = savestack(L, ci->func); /* save current 'func' */ |
| 621 | 580 | if (isLua(ci)) { /* inside a hook? */ |
| 622 | api_check(k == NULL, "hooks cannot continue after yielding"); | |
| 581 | api_check(L, k == NULL, "hooks cannot continue after yielding"); | |
| 623 | 582 | } |
| 624 | 583 | else { |
| 625 | 584 | if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ |
| r242899 | r242900 | |
| 660 | 619 | /* |
| 661 | 620 | ** Execute a protected parser. |
| 662 | 621 | */ |
| 663 | struct SParser { /* data to | |
| 622 | struct SParser { /* data to `f_parser' */ | |
| 664 | 623 | ZIO *z; |
| 665 | 624 | Mbuffer buff; /* dynamic structure used by the scanner */ |
| 666 | 625 | Dyndata dyd; /* dynamic structures used by the parser */ |
| r242899 | r242900 | |
| 672 | 631 | static void checkmode (lua_State *L, const char *mode, const char *x) { |
| 673 | 632 | if (mode && strchr(mode, x[0]) == NULL) { |
| 674 | 633 | luaO_pushfstring(L, |
| 675 | "attempt to load a %s chunk (mode is | |
| 634 | "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); | |
| 676 | 635 | luaD_throw(L, LUA_ERRSYNTAX); |
| 677 | 636 | } |
| 678 | 637 | } |
| 679 | 638 | |
| 680 | 639 | |
| 681 | 640 | static void f_parser (lua_State *L, void *ud) { |
| 682 | LClosure *cl; | |
| 641 | int i; | |
| 642 | Closure *cl; | |
| 683 | 643 | struct SParser *p = cast(struct SParser *, ud); |
| 684 | 644 | int c = zgetc(p->z); /* read first character */ |
| 685 | 645 | if (c == LUA_SIGNATURE[0]) { |
| r242899 | r242900 | |
| 690 | 650 | checkmode(L, p->mode, "text"); |
| 691 | 651 | cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); |
| 692 | 652 | } |
| 693 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); | |
| 694 | luaF_initupvals(L, cl); | |
| 653 | lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); | |
| 654 | for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */ | |
| 655 | UpVal *up = luaF_newupval(L); | |
| 656 | cl->l.upvals[i] = up; | |
| 657 | luaC_objbarrier(L, cl, up); | |
| 658 | } | |
| 695 | 659 | } |
| 696 | 660 | |
| 697 | 661 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ldo.h,v 2.21 201 | |
| 2 | ** $Id: ldo.h,v 2.20.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Stack and Call structure of Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 23 | 23 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) |
| 24 | 24 | |
| 25 | 25 | |
| 26 | /* type of protected functions, to be ran by | |
| 26 | /* type of protected functions, to be ran by `runprotected' */ | |
| 27 | 27 | typedef void (*Pfunc) (lua_State *L, void *ud); |
| 28 | 28 | |
| 29 | 29 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ldump.c,v 2. | |
| 2 | ** $Id: ldump.c,v 2.17.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** save precompiled Lua chunks |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #include <stddef.h> | |
| 8 | ||
| 7 | 9 | #define ldump_c |
| 8 | 10 | #define LUA_CORE |
| 9 | 11 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <stddef.h> | |
| 14 | ||
| 15 | 12 | #include "lua.h" |
| 16 | 13 | |
| 17 | 14 | #include "lobject.h" |
| 18 | 15 | #include "lstate.h" |
| 19 | 16 | #include "lundump.h" |
| 20 | 17 | |
| 21 | ||
| 22 | 18 | typedef struct { |
| 23 | lua_State *L; | |
| 24 | lua_Writer writer; | |
| 25 | void *data; | |
| 26 | int strip; | |
| 27 | int status; | |
| 19 | lua_State* L; | |
| 20 | lua_Writer writer; | |
| 21 | void* data; | |
| 22 | int strip; | |
| 23 | int status; | |
| 28 | 24 | } DumpState; |
| 29 | 25 | |
| 26 | #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) | |
| 27 | #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) | |
| 30 | 28 | |
| 31 | /* | |
| 32 | ** All high-level dumps go through DumpVector; you can change it to | |
| 33 | ** change the endianness of the result | |
| 34 | */ | |
| 35 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) | |
| 36 | ||
| 37 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) | |
| 38 | ||
| 39 | ||
| 40 | static void DumpBlock (const void *b, size_t size, DumpState *D) { | |
| 41 | if (D->status == 0) { | |
| 42 | lua_unlock(D->L); | |
| 43 | D->status = (*D->writer)(D->L, b, size, D->data); | |
| 44 | lua_lock(D->L); | |
| 45 | } | |
| 29 | static void DumpBlock(const void* b, size_t size, DumpState* D) | |
| 30 | { | |
| 31 | if (D->status==0) | |
| 32 | { | |
| 33 | lua_unlock(D->L); | |
| 34 | D->status=(*D->writer)(D->L,b,size,D->data); | |
| 35 | lua_lock(D->L); | |
| 36 | } | |
| 46 | 37 | } |
| 47 | 38 | |
| 48 | ||
| 49 | #define DumpVar(x,D) DumpVector(&x,1,D) | |
| 50 | ||
| 51 | ||
| 52 | static void DumpByte (int y, DumpState *D) { | |
| 53 | lu_byte x = (lu_byte)y; | |
| 54 | DumpVar(x, D); | |
| 39 | static void DumpChar(int y, DumpState* D) | |
| 40 | { | |
| 41 | char x=(char)y; | |
| 42 | DumpVar(x,D); | |
| 55 | 43 | } |
| 56 | 44 | |
| 57 | ||
| 58 | static void DumpInt (int x, DumpState *D) { | |
| 59 | DumpVar(x, D); | |
| 45 | static void DumpInt(int x, DumpState* D) | |
| 46 | { | |
| 47 | DumpVar(x,D); | |
| 60 | 48 | } |
| 61 | 49 | |
| 62 | ||
| 63 | static void DumpNumber (lua_Number x, DumpState *D) { | |
| 64 | DumpVar(x, D); | |
| 50 | static void DumpNumber(lua_Number x, DumpState* D) | |
| 51 | { | |
| 52 | DumpVar(x,D); | |
| 65 | 53 | } |
| 66 | 54 | |
| 67 | ||
| 68 | static void DumpInteger (lua_Integer x, DumpState *D) { | |
| 69 | DumpVar(x, D); | |
| 55 | static void DumpVector(const void* b, int n, size_t size, DumpState* D) | |
| 56 | { | |
| 57 | DumpInt(n,D); | |
| 58 | DumpMem(b,n,size,D); | |
| 70 | 59 | } |
| 71 | 60 | |
| 72 | ||
| 73 | static void DumpString (const TString *s, DumpState *D) { | |
| 74 | if (s == NULL) | |
| 75 | DumpByte(0, D); | |
| 76 | else { | |
| 77 | size_t size = s->len + 1; /* include trailing '\0' */ | |
| 78 | if (size < 0xFF) | |
| 79 | DumpByte(cast_int(size), D); | |
| 80 | else { | |
| 81 | DumpByte(0xFF, D); | |
| 82 | DumpVar(size, D); | |
| 83 | } | |
| 84 | DumpVector(getstr(s), size - 1, D); /* no need to save '\0' */ | |
| 85 | } | |
| 61 | static void DumpString(const TString* s, DumpState* D) | |
| 62 | { | |
| 63 | if (s==NULL) | |
| 64 | { | |
| 65 | size_t size=0; | |
| 66 | DumpVar(size,D); | |
| 67 | } | |
| 68 | else | |
| 69 | { | |
| 70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ | |
| 71 | DumpVar(size,D); | |
| 72 | DumpBlock(getstr(s),size*sizeof(char),D); | |
| 73 | } | |
| 86 | 74 | } |
| 87 | 75 | |
| 76 | #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) | |
| 88 | 77 | |
| 89 | static void DumpCode (const Proto *f, DumpState *D) { | |
| 90 | DumpInt(f->sizecode, D); | |
| 91 | DumpVector(f->code, f->sizecode, D); | |
| 92 | } | |
| 78 | static void DumpFunction(const Proto* f, DumpState* D); | |
| 93 | 79 | |
| 94 | ||
| 95 | static void DumpFunction(const Proto *f, TString *psource, DumpState *D); | |
| 96 | ||
| 97 | static void DumpConstants (const Proto *f, DumpState *D) { | |
| 98 | int i; | |
| 99 | int n = f->sizek; | |
| 100 | DumpInt(n, D); | |
| 101 | for (i = 0; i < n; i++) { | |
| 102 | const TValue *o = &f->k[i]; | |
| 103 | DumpByte(ttype(o), D); | |
| 104 | switch (ttype(o)) { | |
| 105 | case LUA_TNIL: | |
| 106 | break; | |
| 107 | case LUA_TBOOLEAN: | |
| 108 | DumpByte(bvalue(o), D); | |
| 109 | break; | |
| 110 | case LUA_TNUMFLT: | |
| 111 | DumpNumber(fltvalue(o), D); | |
| 112 | break; | |
| 113 | case LUA_TNUMINT: | |
| 114 | DumpInteger(ivalue(o), D); | |
| 115 | break; | |
| 116 | case LUA_TSHRSTR: | |
| 117 | case LUA_TLNGSTR: | |
| 118 | DumpString(tsvalue(o), D); | |
| 119 | break; | |
| 120 | default: | |
| 121 | lua_assert(0); | |
| 122 | } | |
| 80 | static void DumpConstants(const Proto* f, DumpState* D) | |
| 81 | { | |
| 82 | int i,n=f->sizek; | |
| 83 | DumpInt(n,D); | |
| 84 | for (i=0; i<n; i++) | |
| 85 | { | |
| 86 | const TValue* o=&f->k[i]; | |
| 87 | DumpChar(ttypenv(o),D); | |
| 88 | switch (ttypenv(o)) | |
| 89 | { | |
| 90 | case LUA_TNIL: | |
| 91 | break; | |
| 92 | case LUA_TBOOLEAN: | |
| 93 | DumpChar(bvalue(o),D); | |
| 94 | break; | |
| 95 | case LUA_TNUMBER: | |
| 96 | DumpNumber(nvalue(o),D); | |
| 97 | break; | |
| 98 | case LUA_TSTRING: | |
| 99 | DumpString(rawtsvalue(o),D); | |
| 100 | break; | |
| 101 | default: lua_assert(0); | |
| 123 | 102 | } |
| 103 | } | |
| 104 | n=f->sizep; | |
| 105 | DumpInt(n,D); | |
| 106 | for (i=0; i<n; i++) DumpFunction(f->p[i],D); | |
| 124 | 107 | } |
| 125 | 108 | |
| 126 | ||
| 127 | static void DumpProtos (const Proto *f, DumpState *D) { | |
| 128 | int i; | |
| 129 | int n = f->sizep; | |
| 130 | DumpInt(n, D); | |
| 131 | for (i = 0; i < n; i++) | |
| 132 | DumpFunction(f->p[i], f->source, D); | |
| 109 | static void DumpUpvalues(const Proto* f, DumpState* D) | |
| 110 | { | |
| 111 | int i,n=f->sizeupvalues; | |
| 112 | DumpInt(n,D); | |
| 113 | for (i=0; i<n; i++) | |
| 114 | { | |
| 115 | DumpChar(f->upvalues[i].instack,D); | |
| 116 | DumpChar(f->upvalues[i].idx,D); | |
| 117 | } | |
| 133 | 118 | } |
| 134 | 119 | |
| 135 | ||
| 136 | static void DumpUpvalues (const Proto *f, DumpState *D) { | |
| 137 | int i, n = f->sizeupvalues; | |
| 138 | DumpInt(n, D); | |
| 139 | for (i = 0; i < n; i++) { | |
| 140 | DumpByte(f->upvalues[i].instack, D); | |
| 141 | DumpByte(f->upvalues[i].idx, D); | |
| 142 | } | |
| 120 | static void DumpDebug(const Proto* f, DumpState* D) | |
| 121 | { | |
| 122 | int i,n; | |
| 123 | DumpString((D->strip) ? NULL : f->source,D); | |
| 124 | n= (D->strip) ? 0 : f->sizelineinfo; | |
| 125 | DumpVector(f->lineinfo,n,sizeof(int),D); | |
| 126 | n= (D->strip) ? 0 : f->sizelocvars; | |
| 127 | DumpInt(n,D); | |
| 128 | for (i=0; i<n; i++) | |
| 129 | { | |
| 130 | DumpString(f->locvars[i].varname,D); | |
| 131 | DumpInt(f->locvars[i].startpc,D); | |
| 132 | DumpInt(f->locvars[i].endpc,D); | |
| 133 | } | |
| 134 | n= (D->strip) ? 0 : f->sizeupvalues; | |
| 135 | DumpInt(n,D); | |
| 136 | for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D); | |
| 143 | 137 | } |
| 144 | 138 | |
| 145 | ||
| 146 | static void DumpDebug (const Proto *f, DumpState *D) { | |
| 147 | int i, n; | |
| 148 | n = (D->strip) ? 0 : f->sizelineinfo; | |
| 149 | DumpInt(n, D); | |
| 150 | DumpVector(f->lineinfo, n, D); | |
| 151 | n = (D->strip) ? 0 : f->sizelocvars; | |
| 152 | DumpInt(n, D); | |
| 153 | for (i = 0; i < n; i++) { | |
| 154 | DumpString(f->locvars[i].varname, D); | |
| 155 | DumpInt(f->locvars[i].startpc, D); | |
| 156 | DumpInt(f->locvars[i].endpc, D); | |
| 157 | } | |
| 158 | n = (D->strip) ? 0 : f->sizeupvalues; | |
| 159 | DumpInt(n, D); | |
| 160 | for (i = 0; i < n; i++) | |
| 161 | DumpString(f->upvalues[i].name, D); | |
| 139 | static void DumpFunction(const Proto* f, DumpState* D) | |
| 140 | { | |
| 141 | DumpInt(f->linedefined,D); | |
| 142 | DumpInt(f->lastlinedefined,D); | |
| 143 | DumpChar(f->numparams,D); | |
| 144 | DumpChar(f->is_vararg,D); | |
| 145 | DumpChar(f->maxstacksize,D); | |
| 146 | DumpCode(f,D); | |
| 147 | DumpConstants(f,D); | |
| 148 | DumpUpvalues(f,D); | |
| 149 | DumpDebug(f,D); | |
| 162 | 150 | } |
| 163 | 151 | |
| 164 | ||
| 165 | static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { | |
| 166 | if (D->strip || f->source == psource) | |
| 167 | DumpString(NULL, D); /* no debug info or same source as its parent */ | |
| 168 | else | |
| 169 | DumpString(f->source, D); | |
| 170 | DumpInt(f->linedefined, D); | |
| 171 | DumpInt(f->lastlinedefined, D); | |
| 172 | DumpByte(f->numparams, D); | |
| 173 | DumpByte(f->is_vararg, D); | |
| 174 | DumpByte(f->maxstacksize, D); | |
| 175 | DumpCode(f, D); | |
| 176 | DumpConstants(f, D); | |
| 177 | DumpUpvalues(f, D); | |
| 178 | DumpProtos(f, D); | |
| 179 | DumpDebug(f, D); | |
| 152 | static void DumpHeader(DumpState* D) | |
| 153 | { | |
| 154 | lu_byte h[LUAC_HEADERSIZE]; | |
| 155 | luaU_header(h); | |
| 156 | DumpBlock(h,LUAC_HEADERSIZE,D); | |
| 180 | 157 | } |
| 181 | 158 | |
| 182 | ||
| 183 | static void DumpHeader (DumpState *D) { | |
| 184 | DumpLiteral(LUA_SIGNATURE, D); | |
| 185 | DumpByte(LUAC_VERSION, D); | |
| 186 | DumpByte(LUAC_FORMAT, D); | |
| 187 | DumpLiteral(LUAC_DATA, D); | |
| 188 | DumpByte(sizeof(int), D); | |
| 189 | DumpByte(sizeof(size_t), D); | |
| 190 | DumpByte(sizeof(Instruction), D); | |
| 191 | DumpByte(sizeof(lua_Integer), D); | |
| 192 | DumpByte(sizeof(lua_Number), D); | |
| 193 | DumpInteger(LUAC_INT, D); | |
| 194 | DumpNumber(LUAC_NUM, D); | |
| 195 | } | |
| 196 | ||
| 197 | ||
| 198 | 159 | /* |
| 199 | 160 | ** dump Lua function as precompiled chunk |
| 200 | 161 | */ |
| 201 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, | |
| 202 | int strip) { | |
| 203 | DumpState D; | |
| 204 | D.L = L; | |
| 205 | D.writer = w; | |
| 206 | D.data = data; | |
| 207 | D.strip = strip; | |
| 208 | D.status = 0; | |
| 209 | DumpHeader(&D); | |
| 210 | DumpByte(f->sizeupvalues, &D); | |
| 211 | DumpFunction(f, NULL, &D); | |
| 212 | return D.status; | |
| 162 | int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) | |
| 163 | { | |
| 164 | DumpState D; | |
| 165 | D.L=L; | |
| 166 | D.writer=w; | |
| 167 | D.data=data; | |
| 168 | D.strip=strip; | |
| 169 | D.status=0; | |
| 170 | DumpHeader(&D); | |
| 171 | DumpFunction(f,&D); | |
| 172 | return D.status; | |
| 213 | 173 | } |
| 214 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lfunc.c,v 2. | |
| 2 | ** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | ||
| 8 | #include <stddef.h> | |
| 9 | ||
| 7 | 10 | #define lfunc_c |
| 8 | 11 | #define LUA_CORE |
| 9 | 12 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <stddef.h> | |
| 14 | ||
| 15 | 13 | #include "lua.h" |
| 16 | 14 | |
| 17 | 15 | #include "lfunc.h" |
| r242899 | r242900 | |
| 22 | 20 | |
| 23 | 21 | |
| 24 | 22 | |
| 25 | CClosure *luaF_newCclosure (lua_State *L, int n) { | |
| 26 | GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); | |
| 27 | CClosure *c = gco2ccl(o); | |
| 28 | c->nupvalues = cast_byte(n); | |
| 23 | Closure *luaF_newCclosure (lua_State *L, int n) { | |
| 24 | Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; | |
| 25 | c->c.nupvalues = cast_byte(n); | |
| 29 | 26 | return c; |
| 30 | 27 | } |
| 31 | 28 | |
| 32 | 29 | |
| 33 | LClosure *luaF_newLclosure (lua_State *L, int n) { | |
| 34 | GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); | |
| 35 | LClosure *c = gco2lcl(o); | |
| 36 | c->p = NULL; | |
| 37 | c->nupvalues = cast_byte(n); | |
| 38 | while (n--) c->upvals[n] = NULL; | |
| 30 | Closure *luaF_newLclosure (lua_State *L, int n) { | |
| 31 | Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; | |
| 32 | c->l.p = NULL; | |
| 33 | c->l.nupvalues = cast_byte(n); | |
| 34 | while (n--) c->l.upvals[n] = NULL; | |
| 39 | 35 | return c; |
| 40 | 36 | } |
| 41 | 37 | |
| 42 | /* | |
| 43 | ** fill a closure with new closed upvalues | |
| 44 | */ | |
| 45 | void luaF_initupvals (lua_State *L, LClosure *cl) { | |
| 46 | int i; | |
| 47 | for (i = 0; i < cl->nupvalues; i++) { | |
| 48 | UpVal *uv = luaM_new(L, UpVal); | |
| 49 | uv->refcount = 1; | |
| 50 | uv->v = &uv->u.value; /* make it closed */ | |
| 51 | setnilvalue(uv->v); | |
| 52 | cl->upvals[i] = uv; | |
| 53 | } | |
| 38 | ||
| 39 | UpVal *luaF_newupval (lua_State *L) { | |
| 40 | UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; | |
| 41 | uv->v = &uv->u.value; | |
| 42 | setnilvalue(uv->v); | |
| 43 | return uv; | |
| 54 | 44 | } |
| 55 | 45 | |
| 56 | 46 | |
| 57 | 47 | UpVal *luaF_findupval (lua_State *L, StkId level) { |
| 58 | UpVal **pp = &L->openupval; | |
| 48 | global_State *g = G(L); | |
| 49 | GCObject **pp = &L->openupval; | |
| 59 | 50 | UpVal *p; |
| 60 | 51 | UpVal *uv; |
| 61 | lua_assert(isintwups(L) || L->openupval == NULL); | |
| 62 | while (*pp != NULL && (p = *pp)->v >= level) { | |
| 63 | lua_assert(upisopen(p)); | |
| 64 | if (p->v == level) /* found a corresponding upvalue? */ | |
| 65 | return p; /* return it */ | |
| 66 | pp = &p->u.open.next; | |
| 52 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { | |
| 53 | GCObject *o = obj2gco(p); | |
| 54 | lua_assert(p->v != &p->u.value); | |
| 55 | lua_assert(!isold(o) || isold(obj2gco(L))); | |
| 56 | if (p->v == level) { /* found a corresponding upvalue? */ | |
| 57 | if (isdead(g, o)) /* is it dead? */ | |
| 58 | changewhite(o); /* resurrect it */ | |
| 59 | return p; | |
| 60 | } | |
| 61 | pp = &p->next; | |
| 67 | 62 | } |
| 68 | /* not found: create a new upvalue */ | |
| 69 | uv = luaM_new(L, UpVal); | |
| 70 | uv->refcount = 0; | |
| 71 | uv->u.open.next = *pp; /* link it to list of open upvalues */ | |
| 72 | uv->u.open.touched = 1; | |
| 73 | *pp = uv; | |
| 63 | /* not found: create a new one */ | |
| 64 | uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; | |
| 74 | 65 | uv->v = level; /* current value lives in the stack */ |
| 75 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ | |
| 76 | L->twups = G(L)->twups; /* link it to the list */ | |
| 77 | G(L)->twups = L; | |
| 78 | } | |
| 66 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ | |
| 67 | uv->u.l.next = g->uvhead.u.l.next; | |
| 68 | uv->u.l.next->u.l.prev = uv; | |
| 69 | g->uvhead.u.l.next = uv; | |
| 70 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | |
| 79 | 71 | return uv; |
| 80 | 72 | } |
| 81 | 73 | |
| 82 | 74 | |
| 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 | ||
| 83 | 89 | void luaF_close (lua_State *L, StkId level) { |
| 84 | 90 | UpVal *uv; |
| 85 | while (L->openupval != NULL && (uv = L->openupval)->v >= level) { | |
| 86 | lua_assert(upisopen(uv)); | |
| 87 | L->openupval = uv->u.open.next; /* remove from 'open' list */ | |
| 88 | if (uv->refcount == 0) /* no references? */ | |
| 89 | luaM_free(L, uv); /* free upvalue */ | |
| 91 | global_State *g = G(L); | |
| 92 | while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { | |
| 93 | GCObject *o = obj2gco(uv); | |
| 94 | lua_assert(!isblack(o) && uv->v != &uv->u.value); | |
| 95 | L->openupval = uv->next; /* remove from `open' list */ | |
| 96 | if (isdead(g, o)) | |
| 97 | luaF_freeupval(L, uv); /* free upvalue */ | |
| 90 | 98 | else { |
| 99 | unlinkupval(uv); /* remove upvalue from 'uvhead' list */ | |
| 91 | 100 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ |
| 92 | 101 | uv->v = &uv->u.value; /* now current value lives here */ |
| 93 | luaC_upvalbarrier(L, uv); | |
| 102 | gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ | |
| 103 | g->allgc = o; | |
| 104 | luaC_checkupvalcolor(g, uv); | |
| 94 | 105 | } |
| 95 | 106 | } |
| 96 | 107 | } |
| 97 | 108 | |
| 98 | 109 | |
| 99 | 110 | Proto *luaF_newproto (lua_State *L) { |
| 100 | GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); | |
| 101 | Proto *f = gco2p(o); | |
| 111 | Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; | |
| 102 | 112 | f->k = NULL; |
| 103 | 113 | f->sizek = 0; |
| 104 | 114 | f->p = NULL; |
| r242899 | r242900 | |
| 134 | 144 | |
| 135 | 145 | |
| 136 | 146 | /* |
| 137 | ** Look for n-th local variable at line | |
| 147 | ** Look for n-th local variable at line `line' in function `func'. | |
| 138 | 148 | ** Returns NULL if not found. |
| 139 | 149 | */ |
| 140 | 150 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lfunc.h,v 2.1 | |
| 2 | ** $Id: lfunc.h,v 2.8.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 18 | 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 | ||
| 43 | 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); |
| 44 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); | |
| 45 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); | |
| 46 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); | |
| 22 | LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); | |
| 23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); | |
| 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); | |
| 47 | 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); |
| 48 | 26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); |
| 49 | 27 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); |
| 28 | LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); | |
| 50 | 29 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, |
| 51 | 30 | int pc); |
| 52 | 31 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lgc.c,v 2. | |
| 2 | ** $Id: lgc.c,v 2.140.1.2 2013/04/26 18:22:05 roberto Exp $ | |
| 3 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #include <string.h> | |
| 8 | ||
| 7 | 9 | #define lgc_c |
| 8 | 10 | #define LUA_CORE |
| 9 | 11 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <string.h> | |
| 14 | ||
| 15 | 12 | #include "lua.h" |
| 16 | 13 | |
| 17 | 14 | #include "ldebug.h" |
| r242899 | r242900 | |
| 26 | 23 | #include "ltm.h" |
| 27 | 24 | |
| 28 | 25 | |
| 29 | /* | |
| 30 | ** internal state for collector while inside the atomic phase. The | |
| 31 | ** collector should never be in this state while running regular code. | |
| 32 | */ | |
| 33 | #define GCSinsideatomic (GCSpause + 1) | |
| 34 | 26 | |
| 35 | 27 | /* |
| 36 | 28 | ** cost of sweeping one element (the size of a small object divided |
| r242899 | r242900 | |
| 41 | 33 | /* maximum number of elements to sweep in each single step */ |
| 42 | 34 | #define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) |
| 43 | 35 | |
| 44 | /* cost of calling one finalizer */ | |
| 45 | #define GCFINALIZECOST GCSWEEPCOST | |
| 36 | /* maximum number of finalizers to call in each GC step */ | |
| 37 | #define GCFINALIZENUM 4 | |
| 46 | 38 | |
| 47 | 39 | |
| 48 | 40 | /* |
| r242899 | r242900 | |
| 60 | 52 | |
| 61 | 53 | |
| 62 | 54 | /* |
| 63 | ** 'makewhite' erases all color bits then sets only the current white | |
| 64 | ** bit | |
| 55 | ** 'makewhite' erases all color bits plus the old bit and then | |
| 56 | ** sets only the current white bit | |
| 65 | 57 | */ |
| 66 | #define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS)) | |
| 58 | #define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) | |
| 67 | 59 | #define makewhite(g,x) \ |
| 68 | (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g))) | |
| 60 | (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) | |
| 69 | 61 | |
| 70 | #define white2gray(x) resetbits(x->marked, WHITEBITS) | |
| 71 | #define black2gray(x) resetbit(x->marked, BLACKBIT) | |
| 62 | #define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) | |
| 63 | #define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) | |
| 72 | 64 | |
| 73 | 65 | |
| 74 | #define | |
| 66 | #define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) | |
| 75 | 67 | |
| 76 | 68 | #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) |
| 77 | 69 | |
| r242899 | r242900 | |
| 83 | 75 | #define markvalue(g,o) { checkconsistency(o); \ |
| 84 | 76 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } |
| 85 | 77 | |
| 86 | #define markobject(g,t) \ | |
| 87 | { if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); } | |
| 78 | #define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ | |
| 79 | reallymarkobject(g, obj2gco(t)); } | |
| 88 | 80 | |
| 89 | 81 | static void reallymarkobject (global_State *g, GCObject *o); |
| 90 | 82 | |
| r242899 | r242900 | |
| 103 | 95 | |
| 104 | 96 | |
| 105 | 97 | /* |
| 106 | ** link | |
| 98 | ** link table 'h' into list pointed by 'p' | |
| 107 | 99 | */ |
| 108 | #define link | |
| 100 | #define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h)) | |
| 109 | 101 | |
| 110 | 102 | |
| 111 | 103 | /* |
| r242899 | r242900 | |
| 115 | 107 | static void removeentry (Node *n) { |
| 116 | 108 | lua_assert(ttisnil(gval(n))); |
| 117 | 109 | if (valiswhite(gkey(n))) |
| 118 | setdeadvalue( | |
| 110 | setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */ | |
| 119 | 111 | } |
| 120 | 112 | |
| 121 | 113 | |
| 122 | 114 | /* |
| 123 | 115 | ** tells whether a key or value can be cleared from a weak |
| 124 | 116 | ** table. Non-collectable objects are never removed from weak |
| 125 | ** tables. Strings behave as | |
| 117 | ** tables. Strings behave as `values', so are never removed too. for | |
| 126 | 118 | ** other objects: if really collected, cannot keep them; for objects |
| 127 | 119 | ** being finalized, keep them in keys, but not in values |
| 128 | 120 | */ |
| 129 | 121 | static int iscleared (global_State *g, const TValue *o) { |
| 130 | 122 | if (!iscollectable(o)) return 0; |
| 131 | 123 | else if (ttisstring(o)) { |
| 132 | markobject(g, tsvalue(o)); /* strings are | |
| 124 | markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */ | |
| 133 | 125 | return 0; |
| 134 | 126 | } |
| 135 | 127 | else return iswhite(gcvalue(o)); |
| r242899 | r242900 | |
| 138 | 130 | |
| 139 | 131 | /* |
| 140 | 132 | ** barrier that moves collector forward, that is, mark the white object |
| 141 | ** being pointed by a black object. (If in sweep phase, clear the black | |
| 142 | ** object to white [sweep it] to avoid other barrier calls for this | |
| 143 | ** same object.) | |
| 133 | ** being pointed by a black object. | |
| 144 | 134 | */ |
| 145 | 135 | void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { |
| 146 | 136 | global_State *g = G(L); |
| 147 | 137 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
| 148 | if (keepinvariant(g)) /* must keep invariant? */ | |
| 138 | lua_assert(g->gcstate != GCSpause); | |
| 139 | lua_assert(gch(o)->tt != LUA_TTABLE); | |
| 140 | if (keepinvariantout(g)) /* must keep invariant? */ | |
| 149 | 141 | reallymarkobject(g, v); /* restore invariant */ |
| 150 | 142 | else { /* sweep phase */ |
| 151 | 143 | lua_assert(issweepphase(g)); |
| r242899 | r242900 | |
| 156 | 148 | |
| 157 | 149 | /* |
| 158 | 150 | ** barrier that moves collector backward, that is, mark the black object |
| 159 | ** pointing to a white object as gray again. | |
| 151 | ** pointing to a white object as gray again. (Current implementation | |
| 152 | ** only works for tables; access to 'gclist' is not uniform across | |
| 153 | ** different types.) | |
| 160 | 154 | */ |
| 161 | void luaC_barrierback_ (lua_State *L, | |
| 155 | void luaC_barrierback_ (lua_State *L, GCObject *o) { | |
| 162 | 156 | global_State *g = G(L); |
| 163 | lua_assert(isblack(t) && !isdead(g, t)); | |
| 164 | black2gray(t); /* make table gray (again) */ | |
| 165 | linkgclist(t, g->grayagain); | |
| 157 | lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE); | |
| 158 | black2gray(o); /* make object gray (again) */ | |
| 159 | gco2t(o)->gclist = g->grayagain; | |
| 160 | g->grayagain = o; | |
| 166 | 161 | } |
| 167 | 162 | |
| 168 | 163 | |
| 169 | 164 | /* |
| 170 | ** barrier for assignments to closed upvalues. Because upvalues are | |
| 171 | ** shared among closures, it is impossible to know the color of all | |
| 172 | ** closures pointing to it. So, we assume that the object being assigned | |
| 173 | ** must be marked. | |
| 165 | ** barrier for prototypes. When creating first closure (cache is | |
| 166 | ** NULL), use a forward barrier; this may be the only closure of the | |
| 167 | ** prototype (if it is a "regular" function, with a single instance) | |
| 168 | ** and the prototype may be big, so it is better to avoid traversing | |
| 169 | ** it again. Otherwise, use a backward barrier, to avoid marking all | |
| 170 | ** possible instances. | |
| 174 | 171 | */ |
| 175 | void luaC_ | |
| 172 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) { | |
| 176 | 173 | global_State *g = G(L); |
| 177 | GCObject *o = gcvalue(uv->v); | |
| 178 | lua_assert(!upisopen(uv)); /* ensured by macro luaC_upvalbarrier */ | |
| 179 | if (keepinvariant(g)) | |
| 180 | markobject(g, o); | |
| 174 | lua_assert(isblack(obj2gco(p))); | |
| 175 | if (p->cache == NULL) { /* first time? */ | |
| 176 | luaC_objbarrier(L, p, c); | |
| 177 | } | |
| 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 | } | |
| 181 | 183 | } |
| 182 | 184 | |
| 183 | 185 | |
| 184 | void luaC_fix (lua_State *L, GCObject *o) { | |
| 185 | global_State *g = G(L); | |
| 186 | lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ | |
| 187 | white2gray(o); /* they will be gray forever */ | |
| 188 | g->allgc = o->next; /* remove object from 'allgc' list */ | |
| 189 | o->next = g->fixedgc; /* link it to 'fixedgc' list */ | |
| 190 | g->fixedgc = o; | |
| 186 | /* | |
| 187 | ** check color (and invariants) for an upvalue that was closed, | |
| 188 | ** i.e., moved into the 'allgc' list | |
| 189 | */ | |
| 190 | void luaC_checkupvalcolor (global_State *g, UpVal *uv) { | |
| 191 | GCObject *o = obj2gco(uv); | |
| 192 | lua_assert(!isblack(o)); /* open upvalues are never black */ | |
| 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 | } | |
| 191 | 204 | } |
| 192 | 205 | |
| 193 | 206 | |
| 194 | 207 | /* |
| 195 | 208 | ** create a new collectable object (with given type and size) and link |
| 196 | ** it to 'allgc' list. | |
| 209 | ** it to '*list'. 'offset' tells how many bytes to allocate before the | |
| 210 | ** object itself (used only by states). | |
| 197 | 211 | */ |
| 198 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { | |
| 212 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, | |
| 213 | int offset) { | |
| 199 | 214 | global_State *g = G(L); |
| 200 | GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); | |
| 201 | o->marked = luaC_white(g); | |
| 202 | o->tt = tt; | |
| 203 | o->next = g->allgc; | |
| 204 | g->allgc = o; | |
| 215 | char *raw = cast(char *, 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); | |
| 220 | gch(o)->tt = tt; | |
| 221 | gch(o)->next = *list; | |
| 222 | *list = o; | |
| 205 | 223 | return o; |
| 206 | 224 | } |
| 207 | 225 | |
| r242899 | r242900 | |
| 223 | 241 | ** upvalues are already linked in 'headuv' list.) |
| 224 | 242 | */ |
| 225 | 243 | static void reallymarkobject (global_State *g, GCObject *o) { |
| 226 | | |
| 244 | lu_mem size; | |
| 227 | 245 | white2gray(o); |
| 228 | switch (o->tt) { | |
| 246 | switch (gch(o)->tt) { | |
| 229 | 247 | case LUA_TSHRSTR: |
| 230 | 248 | case LUA_TLNGSTR: { |
| 231 | gray2black(o); | |
| 232 | g->GCmemtrav += sizestring(gco2ts(o)); | |
| 233 | break; | |
| 249 | size = sizestring(gco2ts(o)); | |
| 250 | break; /* nothing else to mark; make it black */ | |
| 234 | 251 | } |
| 235 | 252 | case LUA_TUSERDATA: { |
| 236 | TValue uvalue; | |
| 237 | markobject(g, gco2u(o)->metatable); /* mark its metatable */ | |
| 238 | gray2black(o); | |
| 239 | g->GCmemtrav += sizeudata(gco2u(o)); | |
| 240 | getuservalue(g->mainthread, gco2u(o), &uvalue); | |
| 241 | if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */ | |
| 242 | o = gcvalue(&uvalue); | |
| 243 | goto reentry; | |
| 244 | } | |
| 253 | Table *mt = gco2u(o)->metatable; | |
| 254 | markobject(g, mt); | |
| 255 | markobject(g, gco2u(o)->env); | |
| 256 | size = sizeudata(gco2u(o)); | |
| 245 | 257 | break; |
| 246 | 258 | } |
| 247 | case LUA_TLCL: { | |
| 248 | linkgclist(gco2lcl(o), g->gray); | |
| 259 | case LUA_TUPVAL: { | |
| 260 | UpVal *uv = gco2uv(o); | |
| 261 | markvalue(g, uv->v); | |
| 262 | if (uv->v != &uv->u.value) /* open? */ | |
| 263 | return; /* open upvalues remain gray */ | |
| 264 | size = sizeof(UpVal); | |
| 249 | 265 | break; |
| 250 | 266 | } |
| 267 | case LUA_TLCL: { | |
| 268 | gco2lcl(o)->gclist = g->gray; | |
| 269 | g->gray = o; | |
| 270 | return; | |
| 271 | } | |
| 251 | 272 | case LUA_TCCL: { |
| 252 | linkgclist(gco2ccl(o), g->gray); | |
| 253 | break; | |
| 273 | gco2ccl(o)->gclist = g->gray; | |
| 274 | g->gray = o; | |
| 275 | return; | |
| 254 | 276 | } |
| 255 | 277 | case LUA_TTABLE: { |
| 256 | linkgclist(gco2t(o), g->gray); | |
| 257 | break; | |
| 278 | linktable(gco2t(o), &g->gray); | |
| 279 | return; | |
| 258 | 280 | } |
| 259 | 281 | case LUA_TTHREAD: { |
| 260 | linkgclist(gco2th(o), g->gray); | |
| 261 | break; | |
| 282 | gco2th(o)->gclist = g->gray; | |
| 283 | g->gray = o; | |
| 284 | return; | |
| 262 | 285 | } |
| 263 | 286 | case LUA_TPROTO: { |
| 264 | linkgclist(gco2p(o), g->gray); | |
| 265 | break; | |
| 287 | gco2p(o)->gclist = g->gray; | |
| 288 | g->gray = o; | |
| 289 | return; | |
| 266 | 290 | } |
| 267 | default: lua_assert(0); | |
| 291 | default: lua_assert(0); return; | |
| 268 | 292 | } |
| 293 | gray2black(o); | |
| 294 | g->GCmemtrav += size; | |
| 269 | 295 | } |
| 270 | 296 | |
| 271 | 297 | |
| r242899 | r242900 | |
| 284 | 310 | */ |
| 285 | 311 | static void markbeingfnz (global_State *g) { |
| 286 | 312 | GCObject *o; |
| 287 | for (o = g->tobefnz; o != NULL; o = o->next) | |
| 288 | markobject(g, o); | |
| 313 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { | |
| 314 | makewhite(g, o); | |
| 315 | reallymarkobject(g, o); | |
| 316 | } | |
| 289 | 317 | } |
| 290 | 318 | |
| 291 | 319 | |
| 292 | 320 | /* |
| 293 | ** Mark all values stored in marked open upvalues from non-marked threads. | |
| 294 | ** (Values from marked threads were already marked when traversing the | |
| 295 | ** thread.) Remove from the list threads that no longer have upvalues and | |
| 296 | ** not-marked threads. | |
| 321 | ** mark all values stored in marked open upvalues. (See comment in | |
| 322 | ** 'lstate.h'.) | |
| 297 | 323 | */ |
| 298 | 324 | static void remarkupvals (global_State *g) { |
| 299 | lua_State *thread; | |
| 300 | lua_State **p = &g->twups; | |
| 301 | while ((thread = *p) != NULL) { | |
| 302 | lua_assert(!isblack(thread)); /* threads are never black */ | |
| 303 | if (isgray(thread) && thread->openupval != NULL) | |
| 304 | p = &thread->twups; /* keep marked thread with upvalues in the list */ | |
| 305 | else { /* thread is not marked or without upvalues */ | |
| 306 | UpVal *uv; | |
| 307 | *p = thread->twups; /* remove thread from the list */ | |
| 308 | thread->twups = thread; /* mark that it is out of list */ | |
| 309 | for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { | |
| 310 | if (uv->u.open.touched) { | |
| 311 | markvalue(g, uv->v); /* remark upvalue's value */ | |
| 312 | uv->u.open.touched = 0; | |
| 313 | } | |
| 314 | } | |
| 315 | } | |
| 325 | UpVal *uv; | |
| 326 | for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { | |
| 327 | if (isgray(obj2gco(uv))) | |
| 328 | markvalue(g, uv->v); | |
| 316 | 329 | } |
| 317 | 330 | } |
| 318 | 331 | |
| 319 | 332 | |
| 320 | 333 | /* |
| 321 | ** mark root set and reset all gray lists, to start a new collection | |
| 334 | ** mark root set and reset all gray lists, to start a new | |
| 335 | ** incremental (or full) collection | |
| 322 | 336 | */ |
| 323 | 337 | static void restartcollection (global_State *g) { |
| 324 | 338 | g->gray = g->grayagain = NULL; |
| r242899 | r242900 | |
| 338 | 352 | ** ======================================================= |
| 339 | 353 | */ |
| 340 | 354 | |
| 341 | /* | |
| 342 | ** Traverse a table with weak values and link it to proper list. During | |
| 343 | ** propagate phase, keep it in 'grayagain' list, to be revisited in the | |
| 344 | ** atomic phase. In the atomic phase, if table has any white value, | |
| 345 | ** put it in 'weak' list, to be cleared. | |
| 346 | */ | |
| 347 | 355 | static void traverseweakvalue (global_State *g, Table *h) { |
| 348 | 356 | Node *n, *limit = gnodelast(h); |
| 349 | /* if there is array part, assume it may have white values (it is not | |
| 350 | worth traversing it now just to check) */ | |
| 357 | /* if there is array part, assume it may have white values (do not | |
| 358 | traverse it just to check) */ | |
| 351 | 359 | int hasclears = (h->sizearray > 0); |
| 352 | for (n = gnode(h, 0); n < limit; n++) { | |
| 360 | for (n = gnode(h, 0); n < limit; n++) { | |
| 353 | 361 | checkdeadkey(n); |
| 354 | 362 | if (ttisnil(gval(n))) /* entry is empty? */ |
| 355 | 363 | removeentry(n); /* remove it */ |
| r242899 | r242900 | |
| 360 | 368 | hasclears = 1; /* table will have to be cleared */ |
| 361 | 369 | } |
| 362 | 370 | } |
| 363 | if (g->gcstate == GCSpropagate) | |
| 364 | linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ | |
| 365 | else if (hasclears) | |
| 366 | linkgclist(h, g->weak); /* has to be cleared later */ | |
| 371 | if (hasclears) | |
| 372 | linktable(h, &g->weak); /* has to be cleared later */ | |
| 373 | else /* no white values */ | |
| 374 | linktable(h, &g->grayagain); /* no need to clean */ | |
| 367 | 375 | } |
| 368 | 376 | |
| 369 | 377 | |
| 370 | /* | |
| 371 | ** Traverse an ephemeron table and link it to proper list. Returns true | |
| 372 | ** iff any object was marked during this traversal (which implies that | |
| 373 | ** convergence has to continue). During propagation phase, keep table | |
| 374 | ** in 'grayagain' list, to be visited again in the atomic phase. In | |
| 375 | ** the atomic phase, if table has any white->white entry, it has to | |
| 376 | ** be revisited during ephemeron convergence (as that key may turn | |
| 377 | ** black). Otherwise, if it has any white key, table has to be cleared | |
| 378 | ** (in the atomic phase). | |
| 379 | */ | |
| 380 | 378 | static int traverseephemeron (global_State *g, Table *h) { |
| 381 | 379 | int marked = 0; /* true if an object is marked in this traversal */ |
| 382 | 380 | int hasclears = 0; /* true if table has white keys */ |
| 383 | int | |
| 381 | int prop = 0; /* true if table has entry "white-key -> white-value" */ | |
| 384 | 382 | Node *n, *limit = gnodelast(h); |
| 385 | unsigned int i; | |
| 386 | /* traverse array part */ | |
| 383 | int i; | |
| 384 | /* traverse array part (numeric keys are 'strong') */ | |
| 387 | 385 | for (i = 0; i < h->sizearray; i++) { |
| 388 | 386 | if (valiswhite(&h->array[i])) { |
| 389 | 387 | marked = 1; |
| r242899 | r242900 | |
| 398 | 396 | else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ |
| 399 | 397 | hasclears = 1; /* table must be cleared */ |
| 400 | 398 | if (valiswhite(gval(n))) /* value not marked yet? */ |
| 401 | | |
| 399 | prop = 1; /* must propagate again */ | |
| 402 | 400 | } |
| 403 | 401 | else if (valiswhite(gval(n))) { /* value not marked yet? */ |
| 404 | 402 | marked = 1; |
| 405 | 403 | reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ |
| 406 | 404 | } |
| 407 | 405 | } |
| 408 | /* link table into proper list */ | |
| 409 | if (g->gcstate == GCSpropagate) | |
| 410 | linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ | |
| 411 | else if (hasww) /* table has white->white entries? */ | |
| 412 | linkgclist(h, g->ephemeron); /* have to propagate again */ | |
| 413 | else if (hasclears) /* table has white keys? */ | |
| 414 | linkgclist(h, g->allweak); /* may have to clean white keys */ | |
| 406 | if (prop) | |
| 407 | linktable(h, &g->ephemeron); /* have to propagate again */ | |
| 408 | else if (hasclears) /* does table have white keys? */ | |
| 409 | linktable(h, &g->allweak); /* may have to clean white keys */ | |
| 410 | else /* no white keys */ | |
| 411 | linktable(h, &g->grayagain); /* no need to clean */ | |
| 415 | 412 | return marked; |
| 416 | 413 | } |
| 417 | 414 | |
| 418 | 415 | |
| 419 | 416 | static void traversestrongtable (global_State *g, Table *h) { |
| 420 | 417 | Node *n, *limit = gnodelast(h); |
| 421 | | |
| 418 | int i; | |
| 422 | 419 | for (i = 0; i < h->sizearray; i++) /* traverse array part */ |
| 423 | 420 | markvalue(g, &h->array[i]); |
| 424 | 421 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ |
| r242899 | r242900 | |
| 442 | 439 | ((weakkey = strchr(svalue(mode), 'k')), |
| 443 | 440 | (weakvalue = strchr(svalue(mode), 'v')), |
| 444 | 441 | (weakkey || weakvalue))) { /* is really weak? */ |
| 445 | black2gray(h); /* keep table gray */ | |
| 442 | black2gray(obj2gco(h)); /* keep table gray */ | |
| 446 | 443 | if (!weakkey) /* strong keys? */ |
| 447 | 444 | traverseweakvalue(g, h); |
| 448 | 445 | else if (!weakvalue) /* strong values? */ |
| 449 | 446 | traverseephemeron(g, h); |
| 450 | 447 | else /* all weak */ |
| 451 | link | |
| 448 | linktable(h, &g->allweak); /* nothing to traverse now */ | |
| 452 | 449 | } |
| 453 | 450 | else /* not weak */ |
| 454 | 451 | traversestrongtable(g, h); |
| r242899 | r242900 | |
| 459 | 456 | |
| 460 | 457 | static int traverseproto (global_State *g, Proto *f) { |
| 461 | 458 | int i; |
| 462 | if (f->cache && iswhite(f->cache)) | |
| 459 | if (f->cache && iswhite(obj2gco(f->cache))) | |
| 463 | 460 | f->cache = NULL; /* allow cache to be collected */ |
| 464 | 461 | markobject(g, f->source); |
| 465 | 462 | for (i = 0; i < f->sizek; i++) /* mark literals */ |
| r242899 | r242900 | |
| 486 | 483 | return sizeCclosure(cl->nupvalues); |
| 487 | 484 | } |
| 488 | 485 | |
| 489 | /* | |
| 490 | ** open upvalues point to values in a thread, so those values should | |
| 491 | ** be marked when the thread is traversed except in the atomic phase | |
| 492 | ** (because then the value cannot be changed by the thread and the | |
| 493 | ** thread may not be traversed again) | |
| 494 | */ | |
| 495 | 486 | static lu_mem traverseLclosure (global_State *g, LClosure *cl) { |
| 496 | 487 | int i; |
| 497 | 488 | markobject(g, cl->p); /* mark its prototype */ |
| 498 | for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */ | |
| 499 | UpVal *uv = cl->upvals[i]; | |
| 500 | if (uv != NULL) { | |
| 501 | if (upisopen(uv) && g->gcstate != GCSinsideatomic) | |
| 502 | uv->u.open.touched = 1; /* can be marked in 'remarkupvals' */ | |
| 503 | else | |
| 504 | markvalue(g, uv->v); | |
| 505 | } | |
| 506 | } | |
| 489 | for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ | |
| 490 | markobject(g, cl->upvals[i]); | |
| 507 | 491 | return sizeLclosure(cl->nupvalues); |
| 508 | 492 | } |
| 509 | 493 | |
| 510 | 494 | |
| 511 | static lu_mem traversethread (global_State *g, lua_State *th) { | |
| 495 | static lu_mem traversestack (global_State *g, lua_State *th) { | |
| 496 | int n = 0; | |
| 512 | 497 | StkId o = th->stack; |
| 513 | 498 | if (o == NULL) |
| 514 | 499 | return 1; /* stack not completely built yet */ |
| 515 | lua_assert(g->gcstate == GCSinsideatomic || | |
| 516 | th->openupval == NULL || isintwups(th)); | |
| 517 | 500 | for (; o < th->top; o++) /* mark live elements in the stack */ |
| 518 | 501 | markvalue(g, o); |
| 519 | if (g->gcstate == GCS | |
| 502 | if (g->gcstate == GCSatomic) { /* final traversal? */ | |
| 520 | 503 | StkId lim = th->stack + th->stacksize; /* real end of stack */ |
| 521 | 504 | for (; o < lim; o++) /* clear not-marked stack slice */ |
| 522 | 505 | setnilvalue(o); |
| 523 | /* 'remarkupvals' may have removed thread from 'twups' list */ | |
| 524 | if (!isintwups(th) && th->openupval != NULL) { | |
| 525 | th->twups = g->twups; /* link it back to the list */ | |
| 526 | g->twups = th; | |
| 527 | } | |
| 528 | 506 | } |
| 529 | else if (g->gckind != KGC_EMERGENCY) | |
| 530 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ | |
| 531 | return (sizeof(lua_State) + sizeof(TValue) * th->stacksize); | |
| 507 | else { /* count call infos to compute size */ | |
| 508 | CallInfo *ci; | |
| 509 | for (ci = &th->base_ci; ci != th->ci; ci = ci->next) | |
| 510 | n++; | |
| 511 | } | |
| 512 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + | |
| 513 | sizeof(CallInfo) * n; | |
| 532 | 514 | } |
| 533 | 515 | |
| 534 | 516 | |
| r242899 | r242900 | |
| 541 | 523 | GCObject *o = g->gray; |
| 542 | 524 | lua_assert(isgray(o)); |
| 543 | 525 | gray2black(o); |
| 544 | switch (o->tt) { | |
| 526 | switch (gch(o)->tt) { | |
| 545 | 527 | case LUA_TTABLE: { |
| 546 | 528 | Table *h = gco2t(o); |
| 547 | 529 | g->gray = h->gclist; /* remove from 'gray' list */ |
| r242899 | r242900 | |
| 563 | 545 | case LUA_TTHREAD: { |
| 564 | 546 | lua_State *th = gco2th(o); |
| 565 | 547 | g->gray = th->gclist; /* remove from 'gray' list */ |
| 566 | linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ | |
| 548 | th->gclist = g->grayagain; | |
| 549 | g->grayagain = o; /* insert into 'grayagain' list */ | |
| 567 | 550 | black2gray(o); |
| 568 | size = traverset | |
| 551 | size = traversestack(g, th); | |
| 569 | 552 | break; |
| 570 | 553 | } |
| 571 | 554 | case LUA_TPROTO: { |
| r242899 | r242900 | |
| 585 | 568 | } |
| 586 | 569 | |
| 587 | 570 | |
| 571 | static void propagatelist (global_State *g, GCObject *l) { | |
| 572 | lua_assert(g->gray == NULL); /* no grays left */ | |
| 573 | g->gray = l; | |
| 574 | propagateall(g); /* traverse all elements from 'l' */ | |
| 575 | } | |
| 576 | ||
| 577 | /* | |
| 578 | ** retraverse all gray lists. Because tables may be reinserted in other | |
| 579 | ** lists when traversed, traverse the original lists to avoid traversing | |
| 580 | ** twice the same table (which is not wrong, but inefficient) | |
| 581 | */ | |
| 582 | static void retraversegrays (global_State *g) { | |
| 583 | GCObject *weak = g->weak; /* save original lists */ | |
| 584 | GCObject *grayagain = g->grayagain; | |
| 585 | GCObject *ephemeron = g->ephemeron; | |
| 586 | g->weak = g->grayagain = g->ephemeron = NULL; | |
| 587 | propagateall(g); /* traverse main gray list */ | |
| 588 | propagatelist(g, grayagain); | |
| 589 | propagatelist(g, weak); | |
| 590 | propagatelist(g, ephemeron); | |
| 591 | } | |
| 592 | ||
| 593 | ||
| 588 | 594 | static void convergeephemerons (global_State *g) { |
| 589 | 595 | int changed; |
| 590 | 596 | do { |
| 591 | 597 | GCObject *w; |
| 592 | 598 | GCObject *next = g->ephemeron; /* get ephemeron list */ |
| 593 | g->ephemeron = NULL; /* tables | |
| 599 | g->ephemeron = NULL; /* tables will return to this list when traversed */ | |
| 594 | 600 | changed = 0; |
| 595 | 601 | while ((w = next) != NULL) { |
| 596 | 602 | next = gco2t(w)->gclist; |
| r242899 | r242900 | |
| 638 | 644 | for (; l != f; l = gco2t(l)->gclist) { |
| 639 | 645 | Table *h = gco2t(l); |
| 640 | 646 | Node *n, *limit = gnodelast(h); |
| 641 | | |
| 647 | int i; | |
| 642 | 648 | for (i = 0; i < h->sizearray; i++) { |
| 643 | 649 | TValue *o = &h->array[i]; |
| 644 | 650 | if (iscleared(g, o)) /* value was collected? */ |
| r242899 | r242900 | |
| 654 | 660 | } |
| 655 | 661 | |
| 656 | 662 | |
| 657 | void luaC_upvdeccount (lua_State *L, UpVal *uv) { | |
| 658 | lua_assert(uv->refcount > 0); | |
| 659 | uv->refcount--; | |
| 660 | if (uv->refcount == 0 && !upisopen(uv)) | |
| 661 | luaM_free(L, uv); | |
| 662 | } | |
| 663 | ||
| 664 | ||
| 665 | static void freeLclosure (lua_State *L, LClosure *cl) { | |
| 666 | int i; | |
| 667 | for (i = 0; i < cl->nupvalues; i++) { | |
| 668 | UpVal *uv = cl->upvals[i]; | |
| 669 | if (uv) | |
| 670 | luaC_upvdeccount(L, uv); | |
| 671 | } | |
| 672 | luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); | |
| 673 | } | |
| 674 | ||
| 675 | ||
| 676 | 663 | static void freeobj (lua_State *L, GCObject *o) { |
| 677 | switch (o->tt) { | |
| 664 | switch (gch(o)->tt) { | |
| 678 | 665 | case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; |
| 679 | 666 | case LUA_TLCL: { |
| 680 | freeLclosure( | |
| 667 | luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); | |
| 681 | 668 | break; |
| 682 | 669 | } |
| 683 | 670 | case LUA_TCCL: { |
| 684 | 671 | luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); |
| 685 | 672 | break; |
| 686 | 673 | } |
| 674 | case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; | |
| 687 | 675 | case LUA_TTABLE: luaH_free(L, gco2t(o)); break; |
| 688 | 676 | case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; |
| 689 | 677 | case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; |
| 690 | 678 | case LUA_TSHRSTR: |
| 691 | | |
| 679 | G(L)->strt.nuse--; | |
| 692 | 680 | /* go through */ |
| 693 | 681 | case LUA_TLNGSTR: { |
| 694 | 682 | luaM_freemem(L, o, sizestring(gco2ts(o))); |
| r242899 | r242900 | |
| 704 | 692 | |
| 705 | 693 | |
| 706 | 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 | /* | |
| 707 | 709 | ** sweep at most 'count' elements from a list of GCObjects erasing dead |
| 708 | ** objects, where a dead object is one marked with the old (non current) | |
| 709 | ** white; change all non-dead objects back to white, preparing for next | |
| 710 | ** collection cycle. Return where to continue the traversal or NULL if | |
| 711 | ** list is finished. | |
| 710 | ** objects, where a dead (not alive) object is one marked with the "old" | |
| 711 | ** (non current) white and not fixed. | |
| 712 | ** In non-generational mode, change all non-dead objects back to white, | |
| 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. | |
| 712 | 718 | */ |
| 713 | 719 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { |
| 714 | 720 | global_State *g = G(L); |
| 715 | 721 | int ow = otherwhite(g); |
| 716 | int white = luaC_white(g); /* current white */ | |
| 722 | int toclear, toset; /* bits to clear and to set in all live objects */ | |
| 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 | } | |
| 717 | 734 | while (*p != NULL && count-- > 0) { |
| 718 | 735 | GCObject *curr = *p; |
| 719 | int marked = curr->marked; | |
| 736 | int marked = gch(curr)->marked; | |
| 720 | 737 | if (isdeadm(ow, marked)) { /* is 'curr' dead? */ |
| 721 | *p = curr->next; /* remove 'curr' from list */ | |
| 738 | *p = gch(curr)->next; /* remove 'curr' from list */ | |
| 722 | 739 | freeobj(L, curr); /* erase 'curr' */ |
| 723 | 740 | } |
| 724 | else { /* change mark to 'white' */ | |
| 725 | curr->marked = cast_byte((marked & maskcolors) | white); | |
| 726 | p = &curr->next; /* go to next element */ | |
| 741 | else { | |
| 742 | if (testbits(marked, tostop)) | |
| 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 */ | |
| 727 | 749 | } |
| 728 | 750 | } |
| 729 | 751 | return (*p == NULL) ? NULL : p; |
| r242899 | r242900 | |
| 734 | 756 | ** sweep a list until a live object (or end of list) |
| 735 | 757 | */ |
| 736 | 758 | static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { |
| 737 | GCObject **old = p; | |
| 759 | GCObject ** old = p; | |
| 738 | 760 | int i = 0; |
| 739 | 761 | do { |
| 740 | 762 | i++; |
| r242899 | r242900 | |
| 753 | 775 | ** ======================================================= |
| 754 | 776 | */ |
| 755 | 777 | |
| 756 | /* | |
| 757 | ** If possible, free concatenation buffer and shrink string table | |
| 758 | */ | |
| 759 | static void checkSizes (lua_State *L, global_State *g) { | |
| 760 | if (g->gckind != KGC_EMERGENCY) { | |
| 761 | l_mem olddebt = g->GCdebt; | |
| 778 | static void checkSizes (lua_State *L) { | |
| 779 | global_State *g = G(L); | |
| 780 | if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ | |
| 781 | int hs = g->strt.size / 2; /* half the size of the string table */ | |
| 782 | if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ | |
| 783 | luaS_resize(L, hs); /* halve its size */ | |
| 762 | 784 | luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ |
| 763 | if (g->strt.nuse < g->strt.size / 4) /* string table too big? */ | |
| 764 | luaS_resize(L, g->strt.size / 2); /* shrink it a little */ | |
| 765 | g->GCestimate += g->GCdebt - olddebt; /* update estimate */ | |
| 766 | 785 | } |
| 767 | 786 | } |
| 768 | 787 | |
| 769 | 788 | |
| 770 | 789 | static GCObject *udata2finalize (global_State *g) { |
| 771 | 790 | GCObject *o = g->tobefnz; /* get first element */ |
| 772 | lua_assert(tofinalize(o)); | |
| 773 | g->tobefnz = o->next; /* remove it from 'tobefnz' list */ | |
| 774 | o->next = g->allgc; /* return it to 'allgc' list */ | |
| 791 | lua_assert(isfinalized(o)); | |
| 792 | g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ | |
| 793 | gch(o)->next = g->allgc; /* return it to 'allgc' list */ | |
| 775 | 794 | g->allgc = o; |
| 776 | resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ | |
| 777 | if (issweepphase(g)) | |
| 795 | resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | |
| 796 | lua_assert(!isold(o)); /* see MOVE OLD rule */ | |
| 797 | if (!keepinvariantout(g)) /* not keeping invariant? */ | |
| 778 | 798 | makewhite(g, o); /* "sweep" object */ |
| 779 | 799 | return o; |
| 780 | 800 | } |
| r242899 | r242900 | |
| 819 | 839 | |
| 820 | 840 | |
| 821 | 841 | /* |
| 822 | ** call a few (up to 'g->gcfinnum') finalizers | |
| 823 | */ | |
| 824 | static int runafewfinalizers (lua_State *L) { | |
| 825 | global_State *g = G(L); | |
| 826 | unsigned int i; | |
| 827 | lua_assert(!g->tobefnz || g->gcfinnum > 0); | |
| 828 | for (i = 0; g->tobefnz && i < g->gcfinnum; i++) | |
| 829 | GCTM(L, 1); /* call one finalizer */ | |
| 830 | g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */ | |
| 831 | : g->gcfinnum * 2; /* else call a few more next time */ | |
| 832 | return i; | |
| 833 | } | |
| 834 | ||
| 835 | ||
| 836 | /* | |
| 837 | ** call all pending finalizers | |
| 838 | */ | |
| 839 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { | |
| 840 | global_State *g = G(L); | |
| 841 | while (g->tobefnz) | |
| 842 | GCTM(L, propagateerrors); | |
| 843 | } | |
| 844 | ||
| 845 | ||
| 846 | /* | |
| 847 | ** find last 'next' field in list 'p' list (to add elements in its end) | |
| 848 | */ | |
| 849 | static GCObject **findlast (GCObject **p) { | |
| 850 | while (*p != NULL) | |
| 851 | p = &(*p)->next; | |
| 852 | return p; | |
| 853 | } | |
| 854 | ||
| 855 | ||
| 856 | /* | |
| 857 | 842 | ** move all unreachable objects (or 'all' objects) that need |
| 858 | 843 | ** finalization from list 'finobj' to list 'tobefnz' (to be finalized) |
| 859 | 844 | */ |
| 860 | static void separatetobefnz (global_State *g, int all) { | |
| 845 | static void separatetobefnz (lua_State *L, int all) { | |
| 846 | global_State *g = G(L); | |
| 847 | GCObject **p = &g->finobj; | |
| 861 | 848 | GCObject *curr; |
| 862 | GCObject **p = &g->finobj; | |
| 863 | GCObject **lastnext = findlast(&g->tobefnz); | |
| 849 | GCObject **lastnext = &g->tobefnz; | |
| 850 | /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ | |
| 851 | while (*lastnext != NULL) | |
| 852 | lastnext = &gch(*lastnext)->next; | |
| 864 | 853 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ |
| 865 | lua_assert(tofinalize(curr)); | |
| 854 | lua_assert(!isfinalized(curr)); | |
| 855 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); | |
| 866 | 856 | if (!(iswhite(curr) || all)) /* not being collected? */ |
| 867 | p = &curr->next; /* don't bother with it */ | |
| 857 | p = &gch(curr)->next; /* don't bother with it */ | |
| 868 | 858 | else { |
| 869 | *p = curr->next; /* remove 'curr' from 'finobj' list */ | |
| 870 | curr->next = *lastnext; /* link at the end of 'tobefnz' list */ | |
| 859 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ | |
| 860 | *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ | |
| 861 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ | |
| 871 | 862 | *lastnext = curr; |
| 872 | lastnext = &curr->next; | |
| 863 | lastnext = &gch(curr)->next; | |
| 873 | 864 | } |
| 874 | 865 | } |
| 875 | 866 | } |
| r242899 | r242900 | |
| 881 | 872 | */ |
| 882 | 873 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { |
| 883 | 874 | global_State *g = G(L); |
| 884 | if (tofinalize(o) || /* obj. is already marked... */ | |
| 885 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ | |
| 875 | if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ | |
| 876 | isfinalized(o) || /* ... or is finalized... */ | |
| 877 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ | |
| 886 | 878 | return; /* nothing to be done */ |
| 887 | 879 | else { /* move 'o' to 'finobj' list */ |
| 888 | 880 | GCObject **p; |
| 889 | if (issweepphase(g)) { | |
| 890 | makewhite(g, o); /* "sweep" object 'o' */ | |
| 891 | if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ | |
| 892 | g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */ | |
| 881 | GCheader *ho = gch(o); | |
| 882 | if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ | |
| 883 | lua_assert(issweepphase(g)); | |
| 884 | g->sweepgc = sweeptolive(L, g->sweepgc, NULL); | |
| 893 | 885 | } |
| 894 | 886 | /* search for pointer pointing to 'o' */ |
| 895 | for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } | |
| 896 | *p = o->next; /* remove 'o' from 'allgc' list */ | |
| 897 | o->next = g->finobj; /* link it in 'finobj' list */ | |
| 887 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } | |
| 888 | *p = ho->next; /* remove 'o' from root list */ | |
| 889 | ho->next = g->finobj; /* link it in list 'finobj' */ | |
| 898 | 890 | g->finobj = o; |
| 899 | l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ | |
| 891 | l_setbit(ho->marked, SEPARATED); /* mark it as such */ | |
| 892 | if (!keepinvariantout(g)) /* not keeping invariant? */ | |
| 893 | makewhite(g, o); /* "sweep" object */ | |
| 894 | else | |
| 895 | resetoldbit(o); /* see MOVE OLD rule */ | |
| 900 | 896 | } |
| 901 | 897 | } |
| 902 | 898 | |
| 903 | 899 | /* }====================================================== */ |
| 904 | 900 | |
| 905 | 901 | |
| 906 | ||
| 907 | 902 | /* |
| 908 | 903 | ** {====================================================== |
| 909 | 904 | ** GC control |
| r242899 | r242900 | |
| 912 | 907 | |
| 913 | 908 | |
| 914 | 909 | /* |
| 915 | ** Set a reasonable "time" to wait before starting a new GC cycle; cycle | |
| 916 | ** will start when memory use hits threshold. (Division by 'estimate' | |
| 917 | ** should be OK: it cannot be zero (because Lua cannot even start with | |
| 918 | ** less than PAUSEADJ bytes). | |
| 910 | ** set a reasonable "time" to wait before starting a new GC cycle; | |
| 911 | ** cycle will start when memory use hits threshold | |
| 919 | 912 | */ |
| 920 | static void setpause (global_State *g) { | |
| 921 | l_mem threshold, debt; | |
| 922 | l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ | |
| 923 | lua_assert(estimate > 0); | |
| 913 | static void setpause (global_State *g, l_mem estimate) { | |
| 914 | l_mem debt, threshold; | |
| 915 | estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ | |
| 924 | 916 | threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ |
| 925 | 917 | ? estimate * g->gcpause /* no overflow */ |
| 926 | 918 | : MAX_LMEM; /* overflow; truncate to maximum */ |
| 927 | debt = gettotalbytes(g) | |
| 919 | debt = -cast(l_mem, threshold - gettotalbytes(g)); | |
| 928 | 920 | luaE_setdebt(g, debt); |
| 929 | 921 | } |
| 930 | 922 | |
| 931 | 923 | |
| 924 | #define sweepphases \ | |
| 925 | (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) | |
| 926 | ||
| 927 | ||
| 932 | 928 | /* |
| 933 | ** Enter first sweep phase. | |
| 934 | ** The call to 'sweeptolive' makes pointer point to an object inside | |
| 935 | ** the list (instead of to the header), so that the real sweep do not | |
| 936 | ** need to skip objects created between "now" and the start of the real | |
| 937 | ** sweep. | |
| 929 | ** enter first sweep phase (strings) and prepare pointers for other | |
| 930 | ** sweep phases. The calls to 'sweeptolive' make pointers point to an | |
| 931 | ** object inside the list (instead of to the header), so that the real | |
| 932 | ** sweep do not need to skip objects created between "now" and the start | |
| 933 | ** of the real sweep. | |
| 938 | 934 | ** Returns how many objects it swept. |
| 939 | 935 | */ |
| 940 | 936 | static int entersweep (lua_State *L) { |
| 941 | 937 | global_State *g = G(L); |
| 942 | 938 | int n = 0; |
| 943 | g->gcstate = GCSswpallgc; | |
| 944 | lua_assert(g->sweepgc == NULL); | |
| 939 | g->gcstate = GCSsweepstring; | |
| 940 | lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); | |
| 941 | /* prepare to sweep strings, finalizable objects, and regular objects */ | |
| 942 | g->sweepstrgc = 0; | |
| 943 | g->sweepfin = sweeptolive(L, &g->finobj, &n); | |
| 945 | 944 | g->sweepgc = sweeptolive(L, &g->allgc, &n); |
| 946 | 945 | return n; |
| 947 | 946 | } |
| 948 | 947 | |
| 949 | 948 | |
| 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 | ||
| 950 | 983 | void luaC_freeallobjects (lua_State *L) { |
| 951 | 984 | global_State *g = G(L); |
| 952 | separatetobefnz(g, 1); /* separate all objects with finalizers */ | |
| 985 | int i; | |
| 986 | separatetobefnz(L, 1); /* separate all objects with finalizers */ | |
| 953 | 987 | lua_assert(g->finobj == NULL); |
| 954 | 988 | callallpendingfinalizers(L, 0); |
| 955 | lua_assert(g->tobefnz == NULL); | |
| 956 | 989 | g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ |
| 957 | 990 | g->gckind = KGC_NORMAL; |
| 958 | sweepwholelist(L, &g->finobj); | |
| 991 | sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ | |
| 959 | 992 | sweepwholelist(L, &g->allgc); |
| 960 | sweepwholelist(L, &g->fixedgc); /* collect fixed objects */ | |
| 993 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ | |
| 994 | sweepwholelist(L, &g->strt.hash[i]); | |
| 961 | 995 | lua_assert(g->strt.nuse == 0); |
| 962 | 996 | } |
| 963 | 997 | |
| 964 | 998 | |
| 965 | 999 | static l_mem atomic (lua_State *L) { |
| 966 | 1000 | global_State *g = G(L); |
| 967 | l_mem work; | |
| 1001 | l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ | |
| 968 | 1002 | GCObject *origweak, *origall; |
| 969 | GCObject *grayagain = g->grayagain; /* save original list */ | |
| 970 | lua_assert(g->ephemeron == NULL && g->weak == NULL); | |
| 971 | lua_assert(!iswhite(g->mainthread)); | |
| 972 | g->gcstate = GCSinsideatomic; | |
| 973 | g->GCmemtrav = 0; /* start counting work */ | |
| 1003 | lua_assert(!iswhite(obj2gco(g->mainthread))); | |
| 974 | 1004 | markobject(g, L); /* mark running thread */ |
| 975 | 1005 | /* registry and global metatables may be changed by API */ |
| 976 | 1006 | markvalue(g, &g->l_registry); |
| 977 | markmt(g); /* mark | |
| 1007 | markmt(g); /* mark basic metatables */ | |
| 978 | 1008 | /* remark occasional upvalues of (maybe) dead threads */ |
| 979 | 1009 | remarkupvals(g); |
| 980 | 1010 | propagateall(g); /* propagate changes */ |
| 981 | work = g->GCmemtrav; /* stop counting (do not recount 'grayagain') */ | |
| 982 | g->gray = grayagain; | |
| 983 | propagateall(g); /* traverse 'grayagain' list */ | |
| 984 | g->GCmemtrav = 0; /* restart counting */ | |
| 1011 | work += g->GCmemtrav; /* stop counting (do not (re)count grays) */ | |
| 1012 | /* traverse objects caught by write barrier and by 'remarkupvals' */ | |
| 1013 | retraversegrays(g); | |
| 1014 | work -= g->GCmemtrav; /* restart counting */ | |
| 985 | 1015 | convergeephemerons(g); |
| 986 | 1016 | /* at this point, all strongly accessible objects are marked. */ |
| 987 | /* | |
| 1017 | /* clear values from weak tables, before checking finalizers */ | |
| 988 | 1018 | clearvalues(g, g->weak, NULL); |
| 989 | 1019 | clearvalues(g, g->allweak, NULL); |
| 990 | 1020 | origweak = g->weak; origall = g->allweak; |
| 991 | 1021 | work += g->GCmemtrav; /* stop counting (objects being finalized) */ |
| 992 | separatetobefnz(g, 0); /* separate objects to be finalized */ | |
| 993 | g->gcfinnum = 1; /* there may be objects to be finalized */ | |
| 1022 | separatetobefnz(L, 0); /* separate objects to be finalized */ | |
| 994 | 1023 | markbeingfnz(g); /* mark objects that will be finalized */ |
| 995 | propagateall(g); /* remark, to propagate 'resurrection' */ | |
| 996 | g->GCmemtrav = 0; /* restart counting */ | |
| 1024 | propagateall(g); /* remark, to propagate `preserveness' */ | |
| 1025 | work -= g->GCmemtrav; /* restart counting */ | |
| 997 | 1026 | convergeephemerons(g); |
| 998 | 1027 | /* at this point, all resurrected objects are marked. */ |
| 999 | 1028 | /* remove dead objects from weak tables */ |
| 1000 | 1029 | clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ |
| 1001 | clearkeys(g, g->allweak, NULL); /* clear keys from all | |
| 1030 | clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */ | |
| 1002 | 1031 | /* clear values from resurrected weak tables */ |
| 1003 | 1032 | clearvalues(g, g->weak, origweak); |
| 1004 | 1033 | clearvalues(g, g->allweak, origall); |
| r242899 | r242900 | |
| 1008 | 1037 | } |
| 1009 | 1038 | |
| 1010 | 1039 | |
| 1011 | static lu_mem sweepstep (lua_State *L, global_State *g, | |
| 1012 | int nextstate, GCObject **nextlist) { | |
| 1013 | if (g->sweepgc) { | |
| 1014 | l_mem olddebt = g->GCdebt; | |
| 1015 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | |
| 1016 | g->GCestimate += g->GCdebt - olddebt; /* update estimate */ | |
| 1017 | if (g->sweepgc) /* is there still something to sweep? */ | |
| 1018 | return (GCSWEEPMAX * GCSWEEPCOST); | |
| 1019 | } | |
| 1020 | /* else enter next state */ | |
| 1021 | g->gcstate = nextstate; | |
| 1022 | g->sweepgc = nextlist; | |
| 1023 | return 0; | |
| 1024 | } | |
| 1025 | ||
| 1026 | ||
| 1027 | 1040 | static lu_mem singlestep (lua_State *L) { |
| 1028 | 1041 | global_State *g = G(L); |
| 1029 | 1042 | switch (g->gcstate) { |
| 1030 | 1043 | case GCSpause: { |
| 1044 | /* start to count memory traversed */ | |
| 1031 | 1045 | g->GCmemtrav = g->strt.size * sizeof(GCObject*); |
| 1046 | lua_assert(!isgenerational(g)); | |
| 1032 | 1047 | restartcollection(g); |
| 1033 | 1048 | g->gcstate = GCSpropagate; |
| 1034 | 1049 | return g->GCmemtrav; |
| 1035 | 1050 | } |
| 1036 | 1051 | case GCSpropagate: { |
| 1037 | g->GCmemtrav = 0; | |
| 1038 | lua_assert(g->gray); | |
| 1039 | propagatemark(g); | |
| 1040 | if (g->gray == NULL) /* no more gray objects? */ | |
| 1041 | g->gcstate = GCSatomic; /* finish propagate phase */ | |
| 1042 | return g->GCmemtrav; /* memory traversed in this step */ | |
| 1052 | if (g->gray) { | |
| 1053 | lu_mem oldtrav = g->GCmemtrav; | |
| 1054 | propagatemark(g); | |
| 1055 | return g->GCmemtrav - oldtrav; /* memory traversed in this step */ | |
| 1056 | } | |
| 1057 | else { /* no more `gray' objects */ | |
| 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 | } | |
| 1043 | 1067 | } |
| 1044 | case GCSatomic: { | |
| 1045 | lu_mem work; | |
| 1046 | int sw; | |
| 1047 | propagateall(g); /* make sure gray list is empty */ | |
| 1048 | work = atomic(L); /* work is what was traversed by 'atomic' */ | |
| 1049 | sw = entersweep(L); | |
| 1050 | g->GCestimate = gettotalbytes(g); /* first estimate */; | |
| 1051 | return work + sw * GCSWEEPCOST; | |
| 1068 | case GCSsweepstring: { | |
| 1069 | int i; | |
| 1070 | for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) | |
| 1071 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); | |
| 1072 | g->sweepstrgc += i; | |
| 1073 | if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */ | |
| 1074 | g->gcstate = GCSsweepudata; | |
| 1075 | return i * GCSWEEPCOST; | |
| 1052 | 1076 | } |
| 1053 | case GCSswpallgc: { /* sweep "regular" objects */ | |
| 1054 | return sweepstep(L, g, GCSswpfinobj, &g->finobj); | |
| 1077 | case GCSsweepudata: { | |
| 1078 | if (g->sweepfin) { | |
| 1079 | g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); | |
| 1080 | return GCSWEEPMAX*GCSWEEPCOST; | |
| 1081 | } | |
| 1082 | else { | |
| 1083 | g->gcstate = GCSsweep; | |
| 1084 | return 0; | |
| 1085 | } | |
| 1055 | 1086 | } |
| 1056 | case GCSswpfinobj: { /* sweep objects with finalizers */ | |
| 1057 | return sweepstep(L, g, GCSswptobefnz, &g->tobefnz); | |
| 1058 | } | |
| 1059 | case GCSswptobefnz: { /* sweep objects to be finalized */ | |
| 1060 | return sweepstep(L, g, GCSswpend, NULL); | |
| 1061 | } | |
| 1062 | case GCSswpend: { /* finish sweeps */ | |
| 1063 | makewhite(g, g->mainthread); /* sweep main thread */ | |
| 1064 | checkSizes(L, g); | |
| 1065 | g->gcstate = GCScallfin; | |
| 1066 | return 0; | |
| 1067 | } | |
| 1068 | case GCScallfin: { /* call remaining finalizers */ | |
| 1069 | if (g->tobefnz && g->gckind != KGC_EMERGENCY) { | |
| 1070 | int n = runafewfinalizers(L); | |
| 1071 | return (n * GCFINALIZECOST); | |
| 1087 | case GCSsweep: { | |
| 1088 | if (g->sweepgc) { | |
| 1089 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | |
| 1090 | return GCSWEEPMAX*GCSWEEPCOST; | |
| 1072 | 1091 | } |
| 1073 | else { /* emergency mode or no more finalizers */ | |
| 1092 | else { | |
| 1093 | /* sweep main thread */ | |
| 1094 | GCObject *mt = obj2gco(g->mainthread); | |
| 1095 | sweeplist(L, &mt, 1); | |
| 1096 | checkSizes(L); | |
| 1074 | 1097 | g->gcstate = GCSpause; /* finish collection */ |
| 1075 | return | |
| 1098 | return GCSWEEPCOST; | |
| 1076 | 1099 | } |
| 1077 | 1100 | } |
| 1078 | 1101 | default: lua_assert(0); return 0; |
| r242899 | r242900 | |
| 1091 | 1114 | } |
| 1092 | 1115 | |
| 1093 | 1116 | |
| 1094 | /* | |
| 1095 | ** get GC debt and convert it from Kb to 'work units' (avoid zero debt | |
| 1096 | ** and overflows) | |
| 1097 | */ | |
| 1098 | static l_mem getdebt (global_State *g) { | |
| 1117 | static void generationalcollection (lua_State *L) { | |
| 1118 | global_State *g = G(L); | |
| 1119 | lua_assert(g->gcstate == GCSpropagate); | |
| 1120 | if (g->GCestimate == 0) { /* signal for another major collection? */ | |
| 1121 | luaC_fullgc(L, 0); /* perform a full regular collection */ | |
| 1122 | g->GCestimate = gettotalbytes(g); /* update control */ | |
| 1123 | } | |
| 1124 | else { | |
| 1125 | lu_mem estimate = g->GCestimate; | |
| 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 | } | |
| 1137 | ||
| 1138 | ||
| 1139 | static void incstep (lua_State *L) { | |
| 1140 | global_State *g = G(L); | |
| 1099 | 1141 | l_mem debt = g->GCdebt; |
| 1100 | 1142 | 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) */ | |
| 1101 | 1145 | debt = (debt / STEPMULADJ) + 1; |
| 1102 | 1146 | debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; |
| 1103 | return debt; | |
| 1104 | } | |
| 1105 | ||
| 1106 | /* | |
| 1107 | ** performs a basic GC step when collector is running | |
| 1108 | */ | |
| 1109 | void luaC_step (lua_State *L) { | |
| 1110 | global_State *g = G(L); | |
| 1111 | l_mem debt = getdebt(g); /* GC deficit (be paid now) */ | |
| 1112 | if (!g->gcrunning) { /* not running? */ | |
| 1113 | luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */ | |
| 1114 | return; | |
| 1115 | } | |
| 1116 | do { /* repeat until pause or enough "credit" (negative debt) */ | |
| 1117 | lu_mem work = singlestep(L); /* perform one single step */ | |
| 1147 | do { /* always perform at least one single step */ | |
| 1148 | lu_mem work = singlestep(L); /* do some work */ | |
| 1118 | 1149 | debt -= work; |
| 1119 | 1150 | } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); |
| 1120 | 1151 | if (g->gcstate == GCSpause) |
| 1121 | setpause(g); /* pause until next cycle */ | |
| 1152 | setpause(g, g->GCestimate); /* pause until next cycle */ | |
| 1122 | 1153 | else { |
| 1123 | debt = (debt / | |
| 1154 | debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ | |
| 1124 | 1155 | luaE_setdebt(g, debt); |
| 1125 | runafewfinalizers(L); | |
| 1126 | 1156 | } |
| 1127 | 1157 | } |
| 1128 | 1158 | |
| 1129 | 1159 | |
| 1130 | 1160 | /* |
| 1131 | ** Performs a full GC cycle; if 'isemergency', set a flag to avoid | |
| 1132 | ** some operations which could change the interpreter state in some | |
| 1133 | ** unexpected ways (running finalizers and shrinking some structures). | |
| 1134 | ** Before running the collection, check 'keepinvariant'; if it is true, | |
| 1135 | ** there may be some objects marked as black, so the collector has | |
| 1136 | ** to sweep all objects to turn them back to white (as white has not | |
| 1137 | ** changed, nothing will be collected). | |
| 1161 | ** performs a basic GC step | |
| 1138 | 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 | */ | |
| 1177 | void luaC_step (lua_State *L) { | |
| 1178 | global_State *g = G(L); | |
| 1179 | if (g->gcrunning) luaC_forcestep(L); | |
| 1180 | else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ | |
| 1181 | } | |
| 1182 | ||
| 1183 | ||
| 1184 | ||
| 1185 | /* | |
| 1186 | ** performs a full GC cycle; if "isemergency", does not call | |
| 1187 | ** finalizers (which could change stack positions) | |
| 1188 | */ | |
| 1139 | 1189 | void luaC_fullgc (lua_State *L, int isemergency) { |
| 1140 | 1190 | global_State *g = G(L); |
| 1141 | lua_assert(g->gckind == KGC_NORMAL); | |
| 1142 | if (isemergency) g->gckind = KGC_EMERGENCY; /* set flag */ | |
| 1143 | if (keepinvariant(g)) { /* black objects? */ | |
| 1144 | entersweep(L); /* sweep everything to turn them back to white */ | |
| 1191 | int origkind = g->gckind; | |
| 1192 | lua_assert(origkind != KGC_EMERGENCY); | |
| 1193 | if (isemergency) /* do not run finalizers during emergency GC */ | |
| 1194 | g->gckind = KGC_EMERGENCY; | |
| 1195 | else { | |
| 1196 | g->gckind = KGC_NORMAL; | |
| 1197 | callallpendingfinalizers(L, 1); | |
| 1145 | 1198 | } |
| 1199 | if (keepinvariant(g)) { /* may there be some black objects? */ | |
| 1200 | /* must sweep all objects to turn them back to white | |
| 1201 | (as white has not changed, nothing will be collected) */ | |
| 1202 | entersweep(L); | |
| 1203 | } | |
| 1146 | 1204 | /* finish any pending sweep phase to start a new cycle */ |
| 1147 | 1205 | luaC_runtilstate(L, bitmask(GCSpause)); |
| 1148 | 1206 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ |
| 1149 | luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ | |
| 1150 | /* estimate must be correct after a full GC cycle */ | |
| 1151 | lua_assert(g->GCestimate == gettotalbytes(g)); | |
| 1152 | luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ | |
| 1153 | g->gckind = KGC_NORMAL; | |
| 1154 | setpause(g); | |
| 1207 | luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ | |
| 1208 | if (origkind == KGC_GEN) { /* generational mode? */ | |
| 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)); | |
| 1214 | if (!isemergency) /* do not run finalizers during emergency GC */ | |
| 1215 | callallpendingfinalizers(L, 1); | |
| 1155 | 1216 | } |
| 1156 | 1217 | |
| 1157 | 1218 | /* }====================================================== */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lgc.h,v 2.8 | |
| 2 | ** $Id: lgc.h,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 38 | 38 | */ |
| 39 | 39 | #define GCSpropagate 0 |
| 40 | 40 | #define GCSatomic 1 |
| 41 | #define GCSswpallgc 2 | |
| 42 | #define GCSswpfinobj 3 | |
| 43 | #define GCSswptobefnz 4 | |
| 44 | #define GCSswpend 5 | |
| 45 | #define GCScallfin 6 | |
| 46 | #define GCSpause 7 | |
| 41 | #define GCSsweepstring 2 | |
| 42 | #define GCSsweepudata 3 | |
| 43 | #define GCSsweep 4 | |
| 44 | #define GCSpause 5 | |
| 47 | 45 | |
| 48 | 46 | |
| 49 | 47 | #define issweepphase(g) \ |
| 50 | (GCSswp | |
| 48 | (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) | |
| 51 | 49 | |
| 50 | #define isgenerational(g) ((g)->gckind == KGC_GEN) | |
| 52 | 51 | |
| 53 | 52 | /* |
| 54 | ** macro to tell when main invariant (white objects cannot point to black | |
| 55 | ** ones) must be kept. During a collection, the sweep | |
| 53 | ** macros to tell when main invariant (white objects cannot point to black | |
| 54 | ** ones) must be kept. During a non-generational collection, the sweep | |
| 56 | 55 | ** phase may break the invariant, as objects turned white may point to |
| 57 | 56 | ** still-black objects. The invariant is restored when sweep ends and |
| 58 | ** all objects are white again. | |
| 57 | ** all objects are white again. During a generational collection, the | |
| 58 | ** invariant must be kept all times. | |
| 59 | 59 | */ |
| 60 | 60 | |
| 61 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) | |
| 61 | #define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) | |
| 62 | 62 | |
| 63 | 63 | |
| 64 | 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 | ||
| 72 | ||
| 73 | /* | |
| 65 | 74 | ** some useful bit tricks |
| 66 | 75 | */ |
| 67 | 76 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) |
| r242899 | r242900 | |
| 74 | 83 | #define testbit(x,b) testbits(x, bitmask(b)) |
| 75 | 84 | |
| 76 | 85 | |
| 77 | /* Layout for bit use in | |
| 86 | /* Layout for bit use in `marked' field: */ | |
| 78 | 87 | #define WHITE0BIT 0 /* object is white (type 0) */ |
| 79 | 88 | #define WHITE1BIT 1 /* object is white (type 1) */ |
| 80 | 89 | #define BLACKBIT 2 /* object is black */ |
| 81 | #define FINALIZEDBIT 3 /* object has been marked for finalization */ | |
| 90 | #define FINALIZEDBIT 3 /* object has been separated 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) */ | |
| 82 | 94 | /* bit 7 is currently used by tests (luaL_checkmemory) */ |
| 83 | 95 | |
| 84 | 96 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
| 85 | 97 | |
| 86 | 98 | |
| 87 | #define iswhite(x) testbits((x)->marked, WHITEBITS) | |
| 88 | #define isblack(x) testbit((x)->marked, BLACKBIT) | |
| 99 | #define iswhite(x) testbits((x)->gch.marked, WHITEBITS) | |
| 100 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | |
| 89 | 101 | #define isgray(x) /* neither white nor black */ \ |
| 90 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) | |
| 102 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) | |
| 91 | 103 | |
| 92 | #define | |
| 104 | #define isold(x) testbit((x)->gch.marked, OLDBIT) | |
| 93 | 105 | |
| 94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) | |
| 106 | /* MOVE OLD rule: whenever an object is moved to the beginning of | |
| 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) | |
| 95 | 111 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) |
| 96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) | |
| 112 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) | |
| 97 | 113 | |
| 98 | #define changewhite(x) ((x)->marked ^= WHITEBITS) | |
| 99 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT) | |
| 114 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) | |
| 115 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) | |
| 100 | 116 | |
| 117 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) | |
| 118 | ||
| 101 | 119 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
| 102 | 120 | |
| 103 | 121 | |
| r242899 | r242900 | |
| 106 | 124 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) |
| 107 | 125 | |
| 108 | 126 | |
| 109 | #define luaC_barrier(L,p,v) { \ | |
| 110 | if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \ | |
| 127 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ | |
| 111 | 128 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } |
| 112 | 129 | |
| 113 | #define luaC_barrierback(L,p,v) { \ | |
| 114 | if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \ | |
| 130 | #define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ | |
| 115 | 131 | luaC_barrierback_(L,p); } |
| 116 | 132 | |
| 117 | #define luaC_objbarrier(L,p,o) { \ | |
| 118 | if (isblack(p) && iswhite(o)) \ | |
| 133 | #define luaC_objbarrier(L,p,o) \ | |
| 134 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ | |
| 119 | 135 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } |
| 120 | 136 | |
| 121 | #define luaC_upvalbarrier(L,uv) \ | |
| 122 | { if (iscollectable((uv)->v) && !upisopen(uv)) \ | |
| 123 | luaC_upvalbarrier_(L,uv); } | |
| 137 | #define luaC_objbarrierback(L,p,o) \ | |
| 138 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } | |
| 124 | 139 | |
| 125 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); | |
| 140 | #define luaC_barrierproto(L,p,c) \ | |
| 141 | { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } | |
| 142 | ||
| 126 | 143 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
| 127 | 144 | LUAI_FUNC void luaC_step (lua_State *L); |
| 145 | LUAI_FUNC void luaC_forcestep (lua_State *L); | |
| 128 | 146 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); |
| 129 | 147 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
| 130 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); | |
| 148 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, | |
| 149 | GCObject **list, int offset); | |
| 131 | 150 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); |
| 132 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); | |
| 133 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv); | |
| 151 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); | |
| 152 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); | |
| 134 | 153 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); |
| 135 | LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv); | |
| 154 | LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); | |
| 155 | LUAI_FUNC void luaC_changemode (lua_State *L, int mode); | |
| 136 | 156 | |
| 137 | ||
| 138 | 157 | #endif |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: linit.c,v 1.3 | |
| 2 | ** $Id: linit.c,v 1.32.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Initialization of libraries for lua.c and other clients |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | #define linit_c | |
| 9 | #define LUA_LIB | |
| 10 | ||
| 11 | 8 | /* |
| 12 | 9 | ** If you embed Lua in your program and need to open the standard |
| 13 | 10 | ** libraries, call luaL_openlibs in your program. If you need a |
| 14 | 11 | ** different set of libraries, copy this file to your project and edit |
| 15 | 12 | ** it to suit your needs. |
| 16 | ** | |
| 17 | ** You can also *preload* libraries, so that a later 'require' can | |
| 18 | ** open the library, which is already linked to the application. | |
| 19 | ** For that, do the following code: | |
| 20 | ** | |
| 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); | |
| 22 | ** lua_pushcfunction(L, luaopen_modname); | |
| 23 | ** lua_setfield(L, -2, modname); | |
| 24 | ** lua_pop(L, 1); // remove _PRELOAD table | |
| 25 | 13 | */ |
| 26 | 14 | |
| 27 | #include "lprefix.h" | |
| 28 | 15 | |
| 16 | #define linit_c | |
| 17 | #define LUA_LIB | |
| 29 | 18 | |
| 30 | #include <stddef.h> | |
| 31 | ||
| 32 | 19 | #include "lua.h" |
| 33 | 20 | |
| 34 | 21 | #include "lualib.h" |
| r242899 | r242900 | |
| 47 | 34 | {LUA_IOLIBNAME, luaopen_io}, |
| 48 | 35 | {LUA_OSLIBNAME, luaopen_os}, |
| 49 | 36 | {LUA_STRLIBNAME, luaopen_string}, |
| 37 | {LUA_BITLIBNAME, luaopen_bit32}, | |
| 50 | 38 | {LUA_MATHLIBNAME, luaopen_math}, |
| 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, | |
| 52 | 39 | {LUA_DBLIBNAME, luaopen_debug}, |
| 53 | #if defined(LUA_COMPAT_BITLIB) | |
| 54 | {LUA_BITLIBNAME, luaopen_bit32}, | |
| 55 | #endif | |
| 56 | 40 | {NULL, NULL} |
| 57 | 41 | }; |
| 58 | 42 | |
| 59 | 43 | |
| 44 | /* | |
| 45 | ** these libs are preloaded and must be required before used | |
| 46 | */ | |
| 47 | static const luaL_Reg preloadedlibs[] = { | |
| 48 | {NULL, NULL} | |
| 49 | }; | |
| 50 | ||
| 51 | ||
| 60 | 52 | LUALIB_API void luaL_openlibs (lua_State *L) { |
| 61 | 53 | const luaL_Reg *lib; |
| 62 | /* | |
| 54 | /* call open functions from 'loadedlibs' and set results to global table */ | |
| 63 | 55 | for (lib = loadedlibs; lib->func; lib++) { |
| 64 | 56 | luaL_requiref(L, lib->name, lib->func, 1); |
| 65 | 57 | lua_pop(L, 1); /* remove lib */ |
| 66 | 58 | } |
| 59 | /* add open functions from 'preloadedlibs' into 'package.preload' table */ | |
| 60 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); | |
| 61 | for (lib = preloadedlibs; lib->func; lib++) { | |
| 62 | lua_pushcfunction(L, lib->func); | |
| 63 | lua_setfield(L, -2, lib->name); | |
| 64 | } | |
| 65 | lua_pop(L, 1); /* remove _PRELOAD table */ | |
| 67 | 66 | } |
| 68 | 67 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: liolib.c,v 2.1 | |
| 2 | ** $Id: liolib.c,v 2.112.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Standard I/O (and system) library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define liolib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 8 | /* | |
| 9 | ** This definition must come before the inclusion of 'stdio.h'; it | |
| 10 | ** should not affect non-POSIX systems | |
| 11 | */ | |
| 12 | #if !defined(_FILE_OFFSET_BITS) | |
| 13 | #define _LARGEFILE_SOURCE 1 | |
| 14 | #define _FILE_OFFSET_BITS 64 | |
| 15 | #endif | |
| 11 | 16 | |
| 12 | 17 | |
| 13 | #include <ctype.h> | |
| 14 | 18 | #include <errno.h> |
| 15 | #include <locale.h> | |
| 16 | 19 | #include <stdio.h> |
| 17 | 20 | #include <stdlib.h> |
| 18 | 21 | #include <string.h> |
| 19 | 22 | |
| 23 | #define liolib_c | |
| 24 | #define LUA_LIB | |
| 25 | ||
| 20 | 26 | #include "lua.h" |
| 21 | 27 | |
| 22 | 28 | #include "lauxlib.h" |
| 23 | 29 | #include "lualib.h" |
| 24 | 30 | |
| 25 | 31 | |
| 26 | #if !defined(l_checkmode) | |
| 32 | #if !defined(lua_checkmode) | |
| 27 | 33 | |
| 28 | 34 | /* |
| 29 | 35 | ** Check whether 'mode' matches '[rwa]%+?b?'. |
| 30 | 36 | ** Change this macro to accept other modes for 'fopen' besides |
| 31 | 37 | ** the standard ones. |
| 32 | 38 | */ |
| 33 | #define l_checkmode(mode) \ | |
| 39 | #define lua_checkmode(mode) \ | |
| 34 | 40 | (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ |
| 35 | 41 | (*mode != '+' || ++mode) && /* skip if char is '+' */ \ |
| 36 | 42 | (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \ |
| r242899 | r242900 | |
| 40 | 46 | |
| 41 | 47 | /* |
| 42 | 48 | ** {====================================================== |
| 43 | ** l_popen spawns a new process connected to the current | |
| 49 | ** lua_popen spawns a new process connected to the current | |
| 44 | 50 | ** one through the file streams. |
| 45 | 51 | ** ======================================================= |
| 46 | 52 | */ |
| 47 | 53 | |
| 48 | #if !defined(l_popen) | |
| 54 | #if !defined(lua_popen) /* { */ | |
| 49 | 55 | |
| 50 | #if defined(LUA_USE_PO | |
| 56 | #if defined(LUA_USE_POPEN) /* { */ | |
| 51 | 57 | |
| 52 | #define l_popen(L,c,m) (fflush(NULL), popen(c,m)) | |
| 53 | #define l_pclose(L,file) (pclose(file)) | |
| 58 | #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) | |
| 59 | #define lua_pclose(L,file) ((void)L, pclose(file)) | |
| 54 | 60 | |
| 55 | #elif defined(LUA_ | |
| 61 | #elif defined(LUA_WIN) /* }{ */ | |
| 56 | 62 | |
| 57 | #define l_popen(L,c,m) (_popen(c,m)) | |
| 58 | #define l_pclose(L,file) (_pclose(file)) | |
| 63 | #define lua_popen(L,c,m) ((void)L, _popen(c,m)) | |
| 64 | #define lua_pclose(L,file) ((void)L, _pclose(file)) | |
| 59 | 65 | |
| 66 | ||
| 60 | 67 | #else /* }{ */ |
| 61 | 68 | |
| 62 | /* ISO C definitions */ | |
| 63 | #define l_popen(L,c,m) \ | |
| 64 | ((void)((void)c, m), \ | |
| 65 | luaL_error(L, "'popen' not supported"), \ | |
| 66 | (FILE*)0) | |
| 67 | #define l_pclose(L,file) ((void)L, (void)file, -1) | |
| 69 | #define lua_popen(L,c,m) ((void)((void)c, m), \ | |
| 70 | luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) | |
| 71 | #define lua_pclose(L,file) ((void)((void)L, file), -1) | |
| 68 | 72 | |
| 69 | #endif /* } */ | |
| 70 | 73 | |
| 71 | 74 | #endif /* } */ |
| 72 | 75 | |
| 76 | #endif /* } */ | |
| 77 | ||
| 73 | 78 | /* }====================================================== */ |
| 74 | 79 | |
| 75 | 80 | |
| 76 | #if !defined(l_getc) /* { */ | |
| 77 | ||
| 78 | #if defined(LUA_USE_POSIX) | |
| 79 | #define l_getc(f) getc_unlocked(f) | |
| 80 | #define l_lockfile(f) flockfile(f) | |
| 81 | #define l_unlockfile(f) funlockfile(f) | |
| 82 | #else | |
| 83 | #define l_getc(f) getc(f) | |
| 84 | #define l_lockfile(f) ((void)0) | |
| 85 | #define l_unlockfile(f) ((void)0) | |
| 86 | #endif | |
| 87 | ||
| 88 | #endif /* } */ | |
| 89 | ||
| 90 | ||
| 91 | 81 | /* |
| 92 | 82 | ** {====================================================== |
| 93 | ** l_fseek: configuration for longer offsets | |
| 83 | ** lua_fseek: configuration for longer offsets | |
| 94 | 84 | ** ======================================================= |
| 95 | 85 | */ |
| 96 | 86 | |
| 97 | #if !defined(l_fseek) /* { */ | |
| 87 | #if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */ | |
| 98 | 88 | |
| 99 | 89 | #if defined(LUA_USE_POSIX) /* { */ |
| 100 | 90 | |
| 101 | #include <sys/types.h> | |
| 102 | ||
| 103 | 91 | #define l_fseek(f,o,w) fseeko(f,o,w) |
| 104 | 92 | #define l_ftell(f) ftello(f) |
| 105 | 93 | #define l_seeknum off_t |
| 106 | 94 | |
| 107 | #elif defined(LUA_ | |
| 95 | #elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \ | |
| 108 | 96 | && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ |
| 109 | ||
| 110 | 97 | /* Windows (but not DDK) and Visual C++ 2005 or higher */ |
| 98 | ||
| 111 | 99 | #define l_fseek(f,o,w) _fseeki64(f,o,w) |
| 112 | 100 | #define l_ftell(f) _ftelli64(f) |
| 113 | 101 | #define l_seeknum __int64 |
| 114 | 102 | |
| 115 | #e | |
| 103 | #endif /* } */ | |
| 116 | 104 | |
| 117 | /* ISO C definitions */ | |
| 105 | #endif /* } */ | |
| 106 | ||
| 107 | ||
| 108 | #if !defined(l_fseek) /* default definitions */ | |
| 118 | 109 | #define l_fseek(f,o,w) fseek(f,o,w) |
| 119 | 110 | #define l_ftell(f) ftell(f) |
| 120 | 111 | #define l_seeknum long |
| 112 | #endif | |
| 121 | 113 | |
| 122 | #endif /* } */ | |
| 123 | ||
| 124 | #endif /* } */ | |
| 125 | ||
| 126 | 114 | /* }====================================================== */ |
| 127 | 115 | |
| 128 | 116 | |
| 129 | 117 | #define IO_PREFIX "_IO_" |
| 130 | #define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) | |
| 131 | 118 | #define IO_INPUT (IO_PREFIX "input") |
| 132 | 119 | #define IO_OUTPUT (IO_PREFIX "output") |
| 133 | 120 | |
| r242899 | r242900 | |
| 174 | 161 | |
| 175 | 162 | |
| 176 | 163 | /* |
| 177 | ** When creating file handles, always creates a | |
| 164 | ** When creating file handles, always creates a `closed' file handle | |
| 178 | 165 | ** before opening the actual file; so, if there is a memory error, the |
| 179 | 166 | ** file is not left opened. |
| 180 | 167 | */ |
| r242899 | r242900 | |
| 186 | 173 | } |
| 187 | 174 | |
| 188 | 175 | |
| 189 | /* | |
| 190 | ** Calls the 'close' function from a file handle. The 'volatile' avoids | |
| 191 | ** a bug in some versions of the Clang compiler (e.g., clang 3.0 for | |
| 192 | ** 32 bits). | |
| 193 | */ | |
| 194 | 176 | static int aux_close (lua_State *L) { |
| 195 | 177 | LStream *p = tolstream(L); |
| 196 | | |
| 178 | lua_CFunction cf = p->closef; | |
| 197 | 179 | p->closef = NULL; /* mark stream as closed */ |
| 198 | 180 | return (*cf)(L); /* close it */ |
| 199 | 181 | } |
| r242899 | r242900 | |
| 237 | 219 | LStream *p = newfile(L); |
| 238 | 220 | p->f = fopen(fname, mode); |
| 239 | 221 | if (p->f == NULL) |
| 240 | luaL_error(L, "cannot open file | |
| 222 | luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno)); | |
| 241 | 223 | } |
| 242 | 224 | |
| 243 | 225 | |
| r242899 | r242900 | |
| 246 | 228 | const char *mode = luaL_optstring(L, 2, "r"); |
| 247 | 229 | LStream *p = newfile(L); |
| 248 | 230 | const char *md = mode; /* to traverse/check mode */ |
| 249 | luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); | |
| 231 | luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode"); | |
| 250 | 232 | p->f = fopen(filename, mode); |
| 251 | 233 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; |
| 252 | 234 | } |
| r242899 | r242900 | |
| 257 | 239 | */ |
| 258 | 240 | static int io_pclose (lua_State *L) { |
| 259 | 241 | LStream *p = tolstream(L); |
| 260 | return luaL_execresult(L, l_pclose(L, p->f)); | |
| 242 | return luaL_execresult(L, lua_pclose(L, p->f)); | |
| 261 | 243 | } |
| 262 | 244 | |
| 263 | 245 | |
| r242899 | r242900 | |
| 265 | 247 | const char *filename = luaL_checkstring(L, 1); |
| 266 | 248 | const char *mode = luaL_optstring(L, 2, "r"); |
| 267 | 249 | LStream *p = newprefile(L); |
| 268 | p->f = l_popen(L, filename, mode); | |
| 250 | p->f = lua_popen(L, filename, mode); | |
| 269 | 251 | p->closef = &io_pclose; |
| 270 | 252 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; |
| 271 | 253 | } |
| r242899 | r242900 | |
| 283 | 265 | lua_getfield(L, LUA_REGISTRYINDEX, findex); |
| 284 | 266 | p = (LStream *)lua_touserdata(L, -1); |
| 285 | 267 | if (isclosed(p)) |
| 286 | luaL_error(L, "standard %s file is closed", findex + IOPREF | |
| 268 | luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX)); | |
| 287 | 269 | return p->f; |
| 288 | 270 | } |
| 289 | 271 | |
| r242899 | r242900 | |
| 319 | 301 | |
| 320 | 302 | |
| 321 | 303 | static void aux_lines (lua_State *L, int toclose) { |
| 304 | int i; | |
| 322 | 305 | int n = lua_gettop(L) - 1; /* number of arguments to read */ |
| 306 | /* ensure that arguments will fit here and into 'io_readline' stack */ | |
| 307 | luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options"); | |
| 308 | lua_pushvalue(L, 1); /* file handle */ | |
| 323 | 309 | lua_pushinteger(L, n); /* number of arguments to read */ |
| 324 | 310 | lua_pushboolean(L, toclose); /* close/not close file when finished */ |
| 325 | lua_ | |
| 311 | for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */ | |
| 326 | 312 | lua_pushcclosure(L, io_readline, 3 + n); |
| 327 | 313 | } |
| 328 | 314 | |
| r242899 | r242900 | |
| 361 | 347 | */ |
| 362 | 348 | |
| 363 | 349 | |
| 364 | /* maximum length of a numeral */ | |
| 365 | #define MAXRN 200 | |
| 366 | ||
| 367 | /* auxiliary structure used by 'read_number' */ | |
| 368 | typedef struct { | |
| 369 | FILE *f; /* file being read */ | |
| 370 | int c; /* current character (look ahead) */ | |
| 371 | int n; /* number of elements in buffer 'buff' */ | |
| 372 | char buff[MAXRN + 1]; /* +1 for ending '\0' */ | |
| 373 | } RN; | |
| 374 | ||
| 375 | ||
| 376 | /* | |
| 377 | ** Add current char to buffer (if not out of space) and read next one | |
| 378 | */ | |
| 379 | static int nextc (RN *rn) { | |
| 380 | if (rn->n >= MAXRN) { /* buffer overflow? */ | |
| 381 | rn->buff[0] = '\0'; /* invalidate result */ | |
| 382 | return 0; /* fail */ | |
| 383 | } | |
| 384 | else { | |
| 385 | rn->buff[rn->n++] = rn->c; /* save current char */ | |
| 386 | rn->c = l_getc(rn->f); /* read next one */ | |
| 350 | static int read_number (lua_State *L, FILE *f) { | |
| 351 | lua_Number d; | |
| 352 | if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { | |
| 353 | lua_pushnumber(L, d); | |
| 387 | 354 | return 1; |
| 388 | 355 | } |
| 389 | } | |
| 390 | ||
| 391 | ||
| 392 | /* | |
| 393 | ** Accept current char if it is in 'set' (of size 1 or 2) | |
| 394 | */ | |
| 395 | static int test2 (RN *rn, const char *set) { | |
| 396 | if (rn->c == set[0] || (rn->c == set[1] && rn->c != '\0')) | |
| 397 | return nextc(rn); | |
| 398 | else return 0; | |
| 399 | } | |
| 400 | ||
| 401 | ||
| 402 | /* | |
| 403 | ** Read a sequence of (hex)digits | |
| 404 | */ | |
| 405 | static int readdigits (RN *rn, int hex) { | |
| 406 | int count = 0; | |
| 407 | while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn)) | |
| 408 | count++; | |
| 409 | return count; | |
| 410 | } | |
| 411 | ||
| 412 | ||
| 413 | /* access to locale "radix character" (decimal point) */ | |
| 414 | #if !defined(l_getlocaledecpoint) | |
| 415 | #define l_getlocaledecpoint() (localeconv()->decimal_point[0]) | |
| 416 | #endif | |
| 417 | ||
| 418 | ||
| 419 | /* | |
| 420 | ** Read a number: first reads a valid prefix of a numeral into a buffer. | |
| 421 | ** Then it calls 'lua_stringtonumber' to check whether the format is | |
| 422 | ** correct and to convert it to a Lua number | |
| 423 | */ | |
| 424 | static int read_number (lua_State *L, FILE *f) { | |
| 425 | RN rn; | |
| 426 | int count = 0; | |
| 427 | int hex = 0; | |
| 428 | char decp[2] = "."; | |
| 429 | rn.f = f; rn.n = 0; | |
| 430 | decp[0] = l_getlocaledecpoint(); /* get decimal point from locale */ | |
| 431 | l_lockfile(rn.f); | |
| 432 | do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ | |
| 433 | test2(&rn, "-+"); /* optional signal */ | |
| 434 | if (test2(&rn, "0")) { | |
| 435 | if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ | |
| 436 | else count = 1; /* count initial '0' as a valid digit */ | |
| 437 | } | |
| 438 | count += readdigits(&rn, hex); /* integral part */ | |
| 439 | if (test2(&rn, decp)) /* decimal point? */ | |
| 440 | count += readdigits(&rn, hex); /* fractional part */ | |
| 441 | if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ | |
| 442 | test2(&rn, "-+"); /* exponent signal */ | |
| 443 | readdigits(&rn, 0); /* exponent digits */ | |
| 444 | } | |
| 445 | ungetc(rn.c, rn.f); /* unread look-ahead char */ | |
| 446 | l_unlockfile(rn.f); | |
| 447 | rn.buff[rn.n] = '\0'; /* finish string */ | |
| 448 | if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */ | |
| 449 | return 1; /* ok */ | |
| 450 | else { /* invalid format */ | |
| 356 | else { | |
| 451 | 357 | lua_pushnil(L); /* "result" to be removed */ |
| 452 | 358 | return 0; /* read fails */ |
| 453 | 359 | } |
| r242899 | r242900 | |
| 456 | 362 | |
| 457 | 363 | static int test_eof (lua_State *L, FILE *f) { |
| 458 | 364 | int c = getc(f); |
| 459 | ungetc(c, f); | |
| 365 | ungetc(c, f); | |
| 460 | 366 | lua_pushlstring(L, NULL, 0); |
| 461 | 367 | return (c != EOF); |
| 462 | 368 | } |
| r242899 | r242900 | |
| 464 | 370 | |
| 465 | 371 | static int read_line (lua_State *L, FILE *f, int chop) { |
| 466 | 372 | luaL_Buffer b; |
| 467 | int c = '\0'; | |
| 468 | 373 | luaL_buffinit(L, &b); |
| 469 | while (c != EOF && c != '\n') { /* repeat until end of line */ | |
| 470 | char *buff = luaL_prepbuffer(&b); /* pre-allocate buffer */ | |
| 471 | int i = 0; | |
| 472 | l_lockfile(f); /* no memory errors can happen inside the lock */ | |
| 473 | while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') | |
| 474 | buff[i++] = c; | |
| 475 | l_unlockfile(f); | |
| 476 | luaL_addsize(&b, i); | |
| 374 | for (;;) { | |
| 375 | size_t l; | |
| 376 | char *p = luaL_prepbuffer(&b); | |
| 377 | if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ | |
| 378 | luaL_pushresult(&b); /* close buffer */ | |
| 379 | return (lua_rawlen(L, -1) > 0); /* check whether read something */ | |
| 380 | } | |
| 381 | l = strlen(p); | |
| 382 | if (l == 0 || p[l-1] != '\n') | |
| 383 | luaL_addsize(&b, l); | |
| 384 | else { | |
| 385 | luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ | |
| 386 | luaL_pushresult(&b); /* close buffer */ | |
| 387 | return 1; /* read at least an `eol' */ | |
| 388 | } | |
| 477 | 389 | } |
| 478 | if (!chop && c == '\n') /* want a newline and have one? */ | |
| 479 | luaL_addchar(&b, c); /* add ending newline to result */ | |
| 480 | luaL_pushresult(&b); /* close buffer */ | |
| 481 | /* return ok if read something (either a newline or something else) */ | |
| 482 | return (c == '\n' || lua_rawlen(L, -1) > 0); | |
| 483 | 390 | } |
| 484 | 391 | |
| 485 | 392 | |
| 393 | #define MAX_SIZE_T (~(size_t)0) | |
| 394 | ||
| 486 | 395 | static void read_all (lua_State *L, FILE *f) { |
| 487 | size_t | |
| 396 | size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */ | |
| 488 | 397 | luaL_Buffer b; |
| 489 | 398 | luaL_buffinit(L, &b); |
| 490 | do { /* read file in chunks of LUAL_BUFFERSIZE bytes */ | |
| 491 | char *p = luaL_prepbuffsize(&b, LUAL_BUFFERSIZE); | |
| 492 | nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f); | |
| 399 | for (;;) { | |
| 400 | char *p = luaL_prepbuffsize(&b, rlen); | |
| 401 | size_t nr = fread(p, sizeof(char), rlen, f); | |
| 493 | 402 | luaL_addsize(&b, nr); |
| 494 | } while (nr == LUAL_BUFFERSIZE); | |
| 403 | if (nr < rlen) break; /* eof? */ | |
| 404 | else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */ | |
| 405 | rlen *= 2; /* double buffer size at each iteration */ | |
| 406 | } | |
| 495 | 407 | luaL_pushresult(&b); /* close buffer */ |
| 496 | 408 | } |
| 497 | 409 | |
| r242899 | r242900 | |
| 523 | 435 | success = 1; |
| 524 | 436 | for (n = first; nargs-- && success; n++) { |
| 525 | 437 | if (lua_type(L, n) == LUA_TNUMBER) { |
| 526 | size_t l = (size_t)lua | |
| 438 | size_t l = (size_t)lua_tointeger(L, n); | |
| 527 | 439 | success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); |
| 528 | 440 | } |
| 529 | 441 | else { |
| 530 | const char *p = luaL_checkstring(L, n); | |
| 531 | if (*p == '*') p++; /* skip optional '*' (for compatibility) */ | |
| 532 | switch (*p) { | |
| 442 | const char *p = lua_tostring(L, n); | |
| 443 | luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); | |
| 444 | switch (p[1]) { | |
| 533 | 445 | case 'n': /* number */ |
| 534 | 446 | success = read_number(L, f); |
| 535 | 447 | break; |
| r242899 | r242900 | |
| 576 | 488 | if (isclosed(p)) /* file is already closed? */ |
| 577 | 489 | return luaL_error(L, "file is already closed"); |
| 578 | 490 | lua_settop(L , 1); |
| 579 | luaL_checkstack(L, n, "too many arguments"); | |
| 580 | 491 | for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ |
| 581 | 492 | lua_pushvalue(L, lua_upvalueindex(3 + i)); |
| 582 | 493 | n = g_read(L, p->f, 2); /* 'n' is number of results */ |
| 583 | 494 | lua_assert(n > 0); /* should return at least a nil */ |
| 584 | if (lua_ | |
| 495 | if (!lua_isnil(L, -n)) /* read at least one value? */ | |
| 585 | 496 | return n; /* return them */ |
| 586 | 497 | else { /* first result is nil: EOF or error */ |
| 587 | 498 | if (n > 1) { /* is there error information? */ |
| r242899 | r242900 | |
| 606 | 517 | for (; nargs--; arg++) { |
| 607 | 518 | if (lua_type(L, arg) == LUA_TNUMBER) { |
| 608 | 519 | /* optimization: could be done exactly as for strings */ |
| 609 | int len = lua_isinteger(L, arg) | |
| 610 | ? fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg)) | |
| 611 | : fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)); | |
| 612 | status = status && (len > 0); | |
| 520 | status = status && | |
| 521 | fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; | |
| 613 | 522 | } |
| 614 | 523 | else { |
| 615 | 524 | size_t l; |
| r242899 | r242900 | |
| 639 | 548 | static const char *const modenames[] = {"set", "cur", "end", NULL}; |
| 640 | 549 | FILE *f = tofile(L); |
| 641 | 550 | int op = luaL_checkoption(L, 2, "cur", modenames); |
| 642 | lua_ | |
| 551 | lua_Number p3 = luaL_optnumber(L, 3, 0); | |
| 643 | 552 | l_seeknum offset = (l_seeknum)p3; |
| 644 | luaL_argcheck(L, (lua_ | |
| 553 | luaL_argcheck(L, (lua_Number)offset == p3, 3, | |
| 645 | 554 | "not an integer in proper range"); |
| 646 | 555 | op = l_fseek(f, offset, mode[op]); |
| 647 | 556 | if (op) |
| 648 | 557 | return luaL_fileresult(L, 0, NULL); /* error */ |
| 649 | 558 | else { |
| 650 | lua_push | |
| 559 | lua_pushnumber(L, (lua_Number)(1.0 * l_ftell(f))); | |
| 651 | 560 | return 1; |
| 652 | 561 | } |
| 653 | 562 | } |
| r242899 | r242900 | |
| 659 | 568 | FILE *f = tofile(L); |
| 660 | 569 | int op = luaL_checkoption(L, 2, NULL, modenames); |
| 661 | 570 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); |
| 662 | int res = setvbuf(f, NULL, mode[op], | |
| 571 | int res = setvbuf(f, NULL, mode[op], sz); | |
| 663 | 572 | return luaL_fileresult(L, res == 0, NULL); |
| 664 | 573 | } |
| 665 | 574 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: llex.c,v 2. | |
| 2 | ** $Id: llex.c,v 2.63.1.2 2013/08/30 15:49:41 roberto Exp $ | |
| 3 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define llex_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <locale.h> |
| 14 | 9 | #include <string.h> |
| 15 | 10 | |
| 11 | #define llex_c | |
| 12 | #define LUA_CORE | |
| 13 | ||
| 16 | 14 | #include "lua.h" |
| 17 | 15 | |
| 18 | 16 | #include "lctype.h" |
| 19 | 17 | #include "ldo.h" |
| 20 | #include "lgc.h" | |
| 21 | 18 | #include "llex.h" |
| 22 | 19 | #include "lobject.h" |
| 23 | 20 | #include "lparser.h" |
| r242899 | r242900 | |
| 41 | 38 | "end", "false", "for", "function", "goto", "if", |
| 42 | 39 | "in", "local", "nil", "not", "or", "repeat", |
| 43 | 40 | "return", "then", "true", "until", "while", |
| 44 | "//", "..", "...", "==", ">=", "<=", "~=", | |
| 45 | "<<", ">>", "::", "<eof>", | |
| 46 | "<number>", "<integer>", "<name>", "<string>" | |
| 41 | "..", "...", "==", ">=", "<=", "~=", "::", "<eof>", | |
| 42 | "<number>", "<name>", "<string>" | |
| 47 | 43 | }; |
| 48 | 44 | |
| 49 | 45 | |
| r242899 | r242900 | |
| 57 | 53 | Mbuffer *b = ls->buff; |
| 58 | 54 | if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { |
| 59 | 55 | size_t newsize; |
| 60 | if (luaZ_sizebuffer(b) >= MAX_SIZE/2) | |
| 56 | if (luaZ_sizebuffer(b) >= MAX_SIZET/2) | |
| 61 | 57 | lexerror(ls, "lexical element too long", 0); |
| 62 | 58 | newsize = luaZ_sizebuffer(b) * 2; |
| 63 | 59 | luaZ_resizebuffer(ls->L, b, newsize); |
| r242899 | r242900 | |
| 68 | 64 | |
| 69 | 65 | void luaX_init (lua_State *L) { |
| 70 | 66 | int i; |
| 71 | TString *e = luaS_new(L, LUA_ENV); /* create env name */ | |
| 72 | luaC_fix(L, obj2gco(e)); /* never collect this name */ | |
| 73 | 67 | for (i=0; i<NUM_RESERVED; i++) { |
| 74 | 68 | TString *ts = luaS_new(L, luaX_tokens[i]); |
| 75 | luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */ | |
| 76 | ts->extra = cast_byte(i+1); /* reserved word */ | |
| 69 | luaS_fix(ts); /* reserved words are never collected */ | |
| 70 | ts->tsv.extra = cast_byte(i+1); /* reserved word */ | |
| 77 | 71 | } |
| 78 | 72 | } |
| 79 | 73 | |
| 80 | 74 | |
| 81 | 75 | const char *luaX_token2str (LexState *ls, int token) { |
| 82 | 76 | if (token < FIRST_RESERVED) { /* single-byte symbols? */ |
| 83 | lua_assert(token == cast_uchar(token)); | |
| 84 | return luaO_pushfstring(ls->L, "'%c'", token); | |
| 77 | lua_assert(token == cast(unsigned char, token)); | |
| 78 | return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) : | |
| 79 | luaO_pushfstring(ls->L, "char(%d)", token); | |
| 85 | 80 | } |
| 86 | 81 | else { |
| 87 | 82 | const char *s = luaX_tokens[token - FIRST_RESERVED]; |
| 88 | 83 | if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ |
| 89 | return luaO_pushfstring(ls->L, | |
| 84 | return luaO_pushfstring(ls->L, LUA_QS, s); | |
| 90 | 85 | else /* names, strings, and numerals */ |
| 91 | 86 | return s; |
| 92 | 87 | } |
| r242899 | r242900 | |
| 95 | 90 | |
| 96 | 91 | static const char *txtToken (LexState *ls, int token) { |
| 97 | 92 | switch (token) { |
| 98 | case TK_NAME: case TK_STRING: | |
| 99 | case TK_FLT: case TK_INT: | |
| 93 | case TK_NAME: | |
| 94 | case TK_STRING: | |
| 95 | case TK_NUMBER: | |
| 100 | 96 | save(ls, '\0'); |
| 101 | return luaO_pushfstring(ls->L, | |
| 97 | return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); | |
| 102 | 98 | default: |
| 103 | 99 | return luaX_token2str(ls, token); |
| 104 | 100 | } |
| r242899 | r242900 | |
| 121 | 117 | |
| 122 | 118 | |
| 123 | 119 | /* |
| 124 | ** creates a new string and anchors it in scanner's table so that | |
| 125 | ** it will not be collected until the end of the compilation | |
| 126 | ** (by that time it should be anchored somewhere) | |
| 120 | ** creates a new string and anchors it in function's table so that | |
| 121 | ** it will not be collected until the end of the function's compilation | |
| 122 | ** (by that time it should be anchored in function's prototype) | |
| 127 | 123 | */ |
| 128 | 124 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { |
| 129 | 125 | lua_State *L = ls->L; |
| 130 | TValue *o; /* entry for | |
| 126 | TValue *o; /* entry for `str' */ | |
| 131 | 127 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ |
| 132 | 128 | setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ |
| 133 | o = luaH_set(L, ls->h, L->top - 1); | |
| 134 | if (ttisnil(o)) { /* not in use yet? */ | |
| 129 | o = luaH_set(L, ls->fs->h, L->top - 1); | |
| 130 | if (ttisnil(o)) { /* not in use yet? (see 'addK') */ | |
| 135 | 131 | /* boolean value does not need GC barrier; |
| 136 | 132 | table has no metatable, so it does not need to invalidate cache */ |
| 137 | 133 | setbvalue(o, 1); /* t[string] = true */ |
| 138 | 134 | luaC_checkGC(L); |
| 139 | 135 | } |
| 140 | 136 | else { /* string already present */ |
| 141 | ts = tsvalue(keyfromval(o)); /* re-use value previously stored */ | |
| 137 | ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */ | |
| 142 | 138 | } |
| 143 | 139 | L->top--; /* remove string from stack */ |
| 144 | 140 | return ts; |
| r242899 | r242900 | |
| 152 | 148 | static void inclinenumber (LexState *ls) { |
| 153 | 149 | int old = ls->current; |
| 154 | 150 | lua_assert(currIsNewline(ls)); |
| 155 | next(ls); /* skip | |
| 151 | next(ls); /* skip `\n' or `\r' */ | |
| 156 | 152 | if (currIsNewline(ls) && ls->current != old) |
| 157 | next(ls); /* skip | |
| 153 | next(ls); /* skip `\n\r' or `\r\n' */ | |
| 158 | 154 | if (++ls->linenumber >= MAX_INT) |
| 159 | l | |
| 155 | luaX_syntaxerror(ls, "chunk has too many lines"); | |
| 160 | 156 | } |
| 161 | 157 | |
| 162 | 158 | |
| 163 | 159 | void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, |
| 164 | 160 | int firstchar) { |
| 165 | ls->t.token = 0; | |
| 166 | 161 | ls->decpoint = '.'; |
| 167 | 162 | ls->L = L; |
| 168 | 163 | ls->current = firstchar; |
| r242899 | r242900 | |
| 172 | 167 | ls->linenumber = 1; |
| 173 | 168 | ls->lastline = 1; |
| 174 | 169 | ls->source = source; |
| 175 | ls->envn = luaS_new(L, LUA_ENV); /* get env name */ | |
| 170 | ls->envn = luaS_new(L, LUA_ENV); /* create env name */ | |
| 171 | luaS_fix(ls->envn); /* never collect this name */ | |
| 176 | 172 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ |
| 177 | 173 | } |
| 178 | 174 | |
| r242899 | r242900 | |
| 185 | 181 | */ |
| 186 | 182 | |
| 187 | 183 | |
| 188 | static int check_next1 (LexState *ls, int c) { | |
| 189 | if (ls->current == c) { | |
| 190 | next(ls); | |
| 191 | return 1; | |
| 192 | } | |
| 193 | else return 0; | |
| 194 | } | |
| 195 | 184 | |
| 196 | ||
| 197 | /* | |
| 198 | ** Check whether current char is in set 'set' (with two chars) and | |
| 199 | ** saves it | |
| 200 | */ | |
| 201 | static int check_next2 (LexState *ls, const char *set) { | |
| 202 | lua_assert(set[2] == '\0'); | |
| 203 | if (ls->current == set[0] || ls->current == set[1]) { | |
| 204 | save_and_next(ls); | |
| 205 | return 1; | |
| 206 | } | |
| 207 | else return 0; | |
| 185 | static int check_next (LexState *ls, const char *set) { | |
| 186 | if (ls->current == '\0' || !strchr(set, ls->current)) | |
| 187 | return 0; | |
| 188 | save_and_next(ls); | |
| 189 | return 1; | |
| 208 | 190 | } |
| 209 | 191 | |
| 210 | 192 | |
| r242899 | r242900 | |
| 212 | 194 | ** change all characters 'from' in buffer to 'to' |
| 213 | 195 | */ |
| 214 | 196 | static void buffreplace (LexState *ls, char from, char to) { |
| 215 | if (from != to) { | |
| 216 | size_t n = luaZ_bufflen(ls->buff); | |
| 217 | char *p = luaZ_buffer(ls->buff); | |
| 218 | while (n--) | |
| 219 | if (p[n] == from) p[n] = to; | |
| 220 | } | |
| 197 | size_t n = luaZ_bufflen(ls->buff); | |
| 198 | char *p = luaZ_buffer(ls->buff); | |
| 199 | while (n--) | |
| 200 | if (p[n] == from) p[n] = to; | |
| 221 | 201 | } |
| 222 | 202 | |
| 223 | 203 | |
| 224 | #if !defined(l_getlocaledecpoint) | |
| 225 | #define l_getlocaledecpoint() (localeconv()->decimal_point[0]) | |
| 204 | #if !defined(getlocaledecpoint) | |
| 205 | #define getlocaledecpoint() (localeconv()->decimal_point[0]) | |
| 226 | 206 | #endif |
| 227 | 207 | |
| 228 | 208 | |
| 229 | #define buff2 | |
| 209 | #define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e) | |
| 230 | 210 | |
| 231 | 211 | /* |
| 232 | 212 | ** in case of format error, try to change decimal point separator to |
| 233 | 213 | ** the one defined in the current locale and check again |
| 234 | 214 | */ |
| 235 | static void trydecpoint (LexState *ls, | |
| 215 | static void trydecpoint (LexState *ls, SemInfo *seminfo) { | |
| 236 | 216 | char old = ls->decpoint; |
| 237 | ls->decpoint = | |
| 217 | ls->decpoint = getlocaledecpoint(); | |
| 238 | 218 | buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ |
| 239 | if (!buff2 | |
| 219 | if (!buff2d(ls->buff, &seminfo->r)) { | |
| 240 | 220 | /* format error with correct decimal point: no more options */ |
| 241 | 221 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ |
| 242 | lexerror(ls, "malformed number", TK_ | |
| 222 | lexerror(ls, "malformed number", TK_NUMBER); | |
| 243 | 223 | } |
| 244 | 224 | } |
| 245 | 225 | |
| 246 | 226 | |
| 247 | 227 | /* LUA_NUMBER */ |
| 248 | 228 | /* |
| 249 | ** this function is quite liberal in what it accepts, as 'luaO_str2 | |
| 229 | ** this function is quite liberal in what it accepts, as 'luaO_str2d' | |
| 250 | 230 | ** will reject ill-formed numerals. |
| 251 | 231 | */ |
| 252 | static int read_numeral (LexState *ls, SemInfo *seminfo) { | |
| 253 | TValue obj; | |
| 232 | static void read_numeral (LexState *ls, SemInfo *seminfo) { | |
| 254 | 233 | const char *expo = "Ee"; |
| 255 | 234 | int first = ls->current; |
| 256 | 235 | lua_assert(lisdigit(ls->current)); |
| 257 | 236 | save_and_next(ls); |
| 258 | if (first == '0' && check_next | |
| 237 | if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */ | |
| 259 | 238 | expo = "Pp"; |
| 260 | 239 | for (;;) { |
| 261 | if (check_next2(ls, expo)) /* exponent part? */ | |
| 262 | check_next2(ls, "-+"); /* optional exponent sign */ | |
| 263 | if (lisxdigit(ls->current)) | |
| 240 | if (check_next(ls, expo)) /* exponent part? */ | |
| 241 | check_next(ls, "+-"); /* optional exponent sign */ | |
| 242 | if (lisxdigit(ls->current) || ls->current == '.') | |
| 264 | 243 | save_and_next(ls); |
| 265 | else if (ls->current == '.') | |
| 266 | save_and_next(ls); | |
| 267 | else break; | |
| 244 | else break; | |
| 268 | 245 | } |
| 269 | 246 | save(ls, '\0'); |
| 270 | 247 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ |
| 271 | if (!buff2num(ls->buff, &obj)) /* format error? */ | |
| 272 | trydecpoint(ls, &obj); /* try to update decimal point separator */ | |
| 273 | if (ttisinteger(&obj)) { | |
| 274 | seminfo->i = ivalue(&obj); | |
| 275 | return TK_INT; | |
| 276 | } | |
| 277 | else { | |
| 278 | lua_assert(ttisfloat(&obj)); | |
| 279 | seminfo->r = fltvalue(&obj); | |
| 280 | return TK_FLT; | |
| 281 | } | |
| 248 | if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ | |
| 249 | trydecpoint(ls, seminfo); /* try to update decimal point separator */ | |
| 282 | 250 | } |
| 283 | 251 | |
| 284 | 252 | |
| r242899 | r242900 | |
| 300 | 268 | |
| 301 | 269 | |
| 302 | 270 | static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { |
| 303 | int line = ls->linenumber; /* initial line (for error message) */ | |
| 304 | save_and_next(ls); /* skip 2nd '[' */ | |
| 271 | save_and_next(ls); /* skip 2nd `[' */ | |
| 305 | 272 | if (currIsNewline(ls)) /* string starts with a newline? */ |
| 306 | 273 | inclinenumber(ls); /* skip it */ |
| 307 | 274 | for (;;) { |
| 308 | 275 | switch (ls->current) { |
| 309 | case EOZ: { /* error */ | |
| 310 | const char *what = (seminfo ? "string" : "comment"); | |
| 311 | const char *msg = luaO_pushfstring(ls->L, | |
| 312 | "unfinished long %s (starting at line %d)", what, line); | |
| 313 | lexerror(ls, msg, TK_EOS); | |
| 276 | case EOZ: | |
| 277 | lexerror(ls, (seminfo) ? "unfinished long string" : | |
| 278 | "unfinished long comment", TK_EOS); | |
| 314 | 279 | break; /* to avoid warnings */ |
| 315 | } | |
| 316 | 280 | case ']': { |
| 317 | 281 | if (skip_sep(ls) == sep) { |
| 318 | save_and_next(ls); /* skip 2nd | |
| 282 | save_and_next(ls); /* skip 2nd `]' */ | |
| 319 | 283 | goto endloop; |
| 320 | 284 | } |
| 321 | 285 | break; |
| r242899 | r242900 | |
| 338 | 302 | } |
| 339 | 303 | |
| 340 | 304 | |
| 341 | static void esccheck (LexState *ls, int c, const char *msg) { | |
| 342 | if (!c) { | |
| 343 | if (ls->current != EOZ) | |
| 344 | save_and_next(ls); /* add current to buffer for error message */ | |
| 345 | lexerror(ls, msg, TK_STRING); | |
| 346 | } | |
| 305 | static void escerror (LexState *ls, int *c, int n, const char *msg) { | |
| 306 | int i; | |
| 307 | luaZ_resetbuffer(ls->buff); /* prepare error message */ | |
| 308 | save(ls, '\\'); | |
| 309 | for (i = 0; i < n && c[i] != EOZ; i++) | |
| 310 | save(ls, c[i]); | |
| 311 | lexerror(ls, msg, TK_STRING); | |
| 347 | 312 | } |
| 348 | 313 | |
| 349 | 314 | |
| 350 | static int gethexa (LexState *ls) { | |
| 351 | save_and_next(ls); | |
| 352 | esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected"); | |
| 353 | return luaO_hexavalue(ls->current); | |
| 354 | } | |
| 355 | ||
| 356 | ||
| 357 | 315 | static int readhexaesc (LexState *ls) { |
| 358 | int r = gethexa(ls); | |
| 359 | r = (r << 4) + gethexa(ls); | |
| 360 | luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */ | |
| 361 | return r; | |
| 362 | } | |
| 363 | ||
| 364 | ||
| 365 | static unsigned long readutf8esc (LexState *ls) { | |
| 366 | unsigned long r; | |
| 367 | int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */ | |
| 368 | save_and_next(ls); /* skip 'u' */ | |
| 369 | esccheck(ls, ls->current == '{', "missing '{'"); | |
| 370 | r = gethexa(ls); /* must have at least one digit */ | |
| 371 | while ((save_and_next(ls), lisxdigit(ls->current))) { | |
| 372 | i++; | |
| 373 | r = (r << 4) + luaO_hexavalue(ls->current); | |
| 374 | esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large"); | |
| 316 | int c[3], i; /* keep input for error message */ | |
| 317 | int r = 0; /* result accumulator */ | |
| 318 | c[0] = 'x'; /* for error message */ | |
| 319 | for (i = 1; i < 3; i++) { /* read two hexadecimal digits */ | |
| 320 | c[i] = next(ls); | |
| 321 | if (!lisxdigit(c[i])) | |
| 322 | escerror(ls, c, i + 1, "hexadecimal digit expected"); | |
| 323 | r = (r << 4) + luaO_hexavalue(c[i]); | |
| 375 | 324 | } |
| 376 | esccheck(ls, ls->current == '}', "missing '}'"); | |
| 377 | next(ls); /* skip '}' */ | |
| 378 | luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */ | |
| 379 | 325 | return r; |
| 380 | 326 | } |
| 381 | 327 | |
| 382 | 328 | |
| 383 | static void utf8esc (LexState *ls) { | |
| 384 | char buff[UTF8BUFFSZ]; | |
| 385 | int n = luaO_utf8esc(buff, readutf8esc(ls)); | |
| 386 | for (; n > 0; n--) /* add 'buff' to string */ | |
| 387 | save(ls, buff[UTF8BUFFSZ - n]); | |
| 388 | } | |
| 389 | ||
| 390 | ||
| 391 | 329 | static int readdecesc (LexState *ls) { |
| 392 | int i; | |
| 330 | int c[3], i; | |
| 393 | 331 | int r = 0; /* result accumulator */ |
| 394 | 332 | for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ |
| 395 | r = 10*r + ls->current - '0'; | |
| 396 | save_and_next(ls); | |
| 333 | c[i] = ls->current; | |
| 334 | r = 10*r + c[i] - '0'; | |
| 335 | next(ls); | |
| 397 | 336 | } |
| 398 | esccheck(ls, r <= UCHAR_MAX, "decimal escape too large"); | |
| 399 | luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */ | |
| 337 | if (r > UCHAR_MAX) | |
| 338 | escerror(ls, c, i, "decimal escape too large"); | |
| 400 | 339 | return r; |
| 401 | 340 | } |
| 402 | 341 | |
| r242899 | r242900 | |
| 414 | 353 | break; /* to avoid warnings */ |
| 415 | 354 | case '\\': { /* escape sequences */ |
| 416 | 355 | int c; /* final character to be saved */ |
| 417 | | |
| 356 | next(ls); /* do not save the `\' */ | |
| 418 | 357 | switch (ls->current) { |
| 419 | 358 | case 'a': c = '\a'; goto read_save; |
| 420 | 359 | case 'b': c = '\b'; goto read_save; |
| r242899 | r242900 | |
| 424 | 363 | case 't': c = '\t'; goto read_save; |
| 425 | 364 | case 'v': c = '\v'; goto read_save; |
| 426 | 365 | case 'x': c = readhexaesc(ls); goto read_save; |
| 427 | case 'u': utf8esc(ls); goto no_save; | |
| 428 | 366 | case '\n': case '\r': |
| 429 | 367 | inclinenumber(ls); c = '\n'; goto only_save; |
| 430 | 368 | case '\\': case '\"': case '\'': |
| 431 | 369 | c = ls->current; goto read_save; |
| 432 | 370 | case EOZ: goto no_save; /* will raise an error next loop */ |
| 433 | 371 | case 'z': { /* zap following span of spaces */ |
| 434 | luaZ_buffremove(ls->buff, 1); /* remove '\\' */ | |
| 435 | 372 | next(ls); /* skip the 'z' */ |
| 436 | 373 | while (lisspace(ls->current)) { |
| 437 | 374 | if (currIsNewline(ls)) inclinenumber(ls); |
| r242899 | r242900 | |
| 440 | 377 | goto no_save; |
| 441 | 378 | } |
| 442 | 379 | default: { |
| 443 | esccheck(ls, lisdigit(ls->current), "invalid escape sequence"); | |
| 444 | c = readdecesc(ls); /* digital escape '\ddd' */ | |
| 380 | if (!lisdigit(ls->current)) | |
| 381 | escerror(ls, &ls->current, 1, "invalid escape sequence"); | |
| 382 | /* digital escape \ddd */ | |
| 383 | c = readdecesc(ls); | |
| 445 | 384 | goto only_save; |
| 446 | 385 | } |
| 447 | 386 | } |
| 448 | read_save: | |
| 449 | next(ls); | |
| 450 | /* go through */ | |
| 451 | only_save: | |
| 452 | luaZ_buffremove(ls->buff, 1); /* remove '\\' */ | |
| 453 | save(ls, c); | |
| 454 | /* go through */ | |
| 387 | read_save: next(ls); /* read next character */ | |
| 388 | only_save: save(ls, c); /* save 'c' */ | |
| 455 | 389 | no_save: break; |
| 456 | 390 | } |
| 457 | 391 | default: |
| r242899 | r242900 | |
| 483 | 417 | next(ls); |
| 484 | 418 | if (ls->current == '[') { /* long comment? */ |
| 485 | 419 | int sep = skip_sep(ls); |
| 486 | luaZ_resetbuffer(ls->buff); /* | |
| 420 | luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ | |
| 487 | 421 | if (sep >= 0) { |
| 488 | 422 | read_long_string(ls, NULL, sep); /* skip long comment */ |
| 489 | 423 | luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ |
| r242899 | r242900 | |
| 506 | 440 | } |
| 507 | 441 | case '=': { |
| 508 | 442 | next(ls); |
| 509 | if (check_next1(ls, '=')) return TK_EQ; | |
| 510 | else return '='; | |
| 443 | if (ls->current != '=') return '='; | |
| 444 | else { next(ls); return TK_EQ; } | |
| 511 | 445 | } |
| 512 | 446 | case '<': { |
| 513 | 447 | next(ls); |
| 514 | if (check_next1(ls, '=')) return TK_LE; | |
| 515 | else if (check_next1(ls, '<')) return TK_SHL; | |
| 516 | else return '<'; | |
| 448 | if (ls->current != '=') return '<'; | |
| 449 | else { next(ls); return TK_LE; } | |
| 517 | 450 | } |
| 518 | 451 | case '>': { |
| 519 | 452 | next(ls); |
| 520 | if (check_next1(ls, '=')) return TK_GE; | |
| 521 | else if (check_next1(ls, '>')) return TK_SHR; | |
| 522 | else return '>'; | |
| 453 | if (ls->current != '=') return '>'; | |
| 454 | else { next(ls); return TK_GE; } | |
| 523 | 455 | } |
| 524 | case '/': { | |
| 525 | next(ls); | |
| 526 | if (check_next1(ls, '/')) return TK_IDIV; | |
| 527 | else return '/'; | |
| 528 | } | |
| 529 | 456 | case '~': { |
| 530 | 457 | next(ls); |
| 531 | if (check_next1(ls, '=')) return TK_NE; | |
| 532 | else return '~'; | |
| 458 | if (ls->current != '=') return '~'; | |
| 459 | else { next(ls); return TK_NE; } | |
| 533 | 460 | } |
| 534 | 461 | case ':': { |
| 535 | 462 | next(ls); |
| 536 | if (check_next1(ls, ':')) return TK_DBCOLON; | |
| 537 | else return ':'; | |
| 463 | if (ls->current != ':') return ':'; | |
| 464 | else { next(ls); return TK_DBCOLON; } | |
| 538 | 465 | } |
| 539 | 466 | case '"': case '\'': { /* short literal strings */ |
| 540 | 467 | read_string(ls, ls->current, seminfo); |
| r242899 | r242900 | |
| 542 | 469 | } |
| 543 | 470 | case '.': { /* '.', '..', '...', or number */ |
| 544 | 471 | save_and_next(ls); |
| 545 | if (check_next1(ls, '.')) { | |
| 546 | if (check_next1(ls, '.')) | |
| 472 | if (check_next(ls, ".")) { | |
| 473 | if (check_next(ls, ".")) | |
| 547 | 474 | return TK_DOTS; /* '...' */ |
| 548 | 475 | else return TK_CONCAT; /* '..' */ |
| 549 | 476 | } |
| 550 | 477 | else if (!lisdigit(ls->current)) return '.'; |
| 551 | else | |
| 478 | /* else go through */ | |
| 552 | 479 | } |
| 553 | 480 | case '0': case '1': case '2': case '3': case '4': |
| 554 | 481 | case '5': case '6': case '7': case '8': case '9': { |
| 555 | return read_numeral(ls, seminfo); | |
| 482 | read_numeral(ls, seminfo); | |
| 483 | return TK_NUMBER; | |
| 556 | 484 | } |
| 557 | 485 | case EOZ: { |
| 558 | 486 | return TK_EOS; |
| r242899 | r242900 | |
| 567 | 495 | luaZ_bufflen(ls->buff)); |
| 568 | 496 | seminfo->ts = ts; |
| 569 | 497 | if (isreserved(ts)) /* reserved word? */ |
| 570 | return ts->extra - 1 + FIRST_RESERVED; | |
| 498 | return ts->tsv.extra - 1 + FIRST_RESERVED; | |
| 571 | 499 | else { |
| 572 | 500 | return TK_NAME; |
| 573 | 501 | } |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: llex.h,v 1.7 | |
| 2 | ** $Id: llex.h,v 1.72.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 14 | 14 | #define FIRST_RESERVED 257 |
| 15 | 15 | |
| 16 | 16 | |
| 17 | #if !defined(LUA_ENV) | |
| 18 | #define LUA_ENV "_ENV" | |
| 19 | #endif | |
| 20 | 17 | |
| 21 | ||
| 22 | 18 | /* |
| 23 | 19 | * WARNING: if you change the order of this enumeration, |
| 24 | 20 | * grep "ORDER RESERVED" |
| r242899 | r242900 | |
| 30 | 26 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, |
| 31 | 27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, |
| 32 | 28 | /* other terminal symbols */ |
| 33 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, | |
| 34 | TK_SHL, TK_SHR, | |
| 35 | TK_DBCOLON, TK_EOS, | |
| 36 | TK_FLT, TK_INT, TK_NAME, TK_STRING | |
| 29 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS, | |
| 30 | TK_NUMBER, TK_NAME, TK_STRING | |
| 37 | 31 | }; |
| 38 | 32 | |
| 39 | 33 | /* number of reserved words */ |
| r242899 | r242900 | |
| 42 | 36 | |
| 43 | 37 | typedef union { |
| 44 | 38 | lua_Number r; |
| 45 | lua_Integer i; | |
| 46 | 39 | TString *ts; |
| 47 | 40 | } SemInfo; /* semantics information */ |
| 48 | 41 | |
| r242899 | r242900 | |
| 58 | 51 | typedef struct LexState { |
| 59 | 52 | int current; /* current character (charint) */ |
| 60 | 53 | int linenumber; /* input line counter */ |
| 61 | int lastline; /* line of last token | |
| 54 | int lastline; /* line of last token `consumed' */ | |
| 62 | 55 | Token t; /* current token */ |
| 63 | 56 | Token lookahead; /* look ahead token */ |
| 64 | 57 | struct FuncState *fs; /* current function (parser) */ |
| 65 | 58 | struct lua_State *L; |
| 66 | 59 | ZIO *z; /* input stream */ |
| 67 | 60 | Mbuffer *buff; /* buffer for tokens */ |
| 68 | Table *h; /* to avoid collection/reuse strings */ | |
| 69 | 61 | struct Dyndata *dyd; /* dynamic structures used by the parser */ |
| 70 | 62 | TString *source; /* current source name */ |
| 71 | 63 | TString *envn; /* environment variable name */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: llimits.h,v 1.125 2014/12/19 13:30:23 roberto Exp $ | |
| 3 | ** Limits, basic types, and some other 'installation-dependent' definitions | |
| 2 | ** $Id: llimits.h,v 1.103.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | ** Limits, basic types, and some other `installation-dependent' definitions | |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| r242899 | r242900 | |
| 14 | 14 | |
| 15 | 15 | #include "lua.h" |
| 16 | 16 | |
| 17 | /* | |
| 18 | ** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count | |
| 19 | ** the total memory used by Lua (in bytes). Usually, 'size_t' and | |
| 20 | ** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. | |
| 21 | */ | |
| 22 | #if defined(LUAI_MEM) /* { external definitions? */ | |
| 17 | ||
| 18 | typedef unsigned LUA_INT32 lu_int32; | |
| 19 | ||
| 23 | 20 | typedef LUAI_UMEM lu_mem; |
| 21 | ||
| 24 | 22 | typedef LUAI_MEM l_mem; |
| 25 | #elif LUAI_BITSINT >= 32 /* }{ */ | |
| 26 | typedef size_t lu_mem; | |
| 27 | typedef ptrdiff_t l_mem; | |
| 28 | #else /* 16-bit ints */ /* }{ */ | |
| 29 | typedef unsigned long lu_mem; | |
| 30 | typedef long l_mem; | |
| 31 | #endif /* } */ | |
| 32 | 23 | |
| 33 | 24 | |
| 34 | /* chars used as small naturals (so that 'char' is reserved for characters) */ | |
| 25 | ||
| 26 | /* chars used as small naturals (so that `char' is reserved for characters) */ | |
| 35 | 27 | typedef unsigned char lu_byte; |
| 36 | 28 | |
| 37 | 29 | |
| 38 | /* maximum value for size_t */ | |
| 39 | #define MAX_SIZET ((size_t)(~(size_t)0)) | |
| 30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) | |
| 40 | 31 | |
| 41 | /* maximum size visible for Lua (must be representable in a lua_Integer */ | |
| 42 | #define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ | |
| 43 | : (size_t)(LUA_MAXINTEGER)) | |
| 32 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) | |
| 44 | 33 | |
| 34 | #define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2)) | |
| 45 | 35 | |
| 46 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) | |
| 47 | 36 | |
| 48 | #define MAX_ | |
| 37 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ | |
| 49 | 38 | |
| 50 | ||
| 51 | #define MAX_INT INT_MAX /* maximum value of an int */ | |
| 52 | ||
| 53 | ||
| 54 | 39 | /* |
| 55 | ** conversion of pointer to integer | |
| 40 | ** conversion of pointer to integer | |
| 56 | 41 | ** this is for hashing only; there is no problem if the integer |
| 57 | 42 | ** cannot hold the whole pointer value |
| 58 | 43 | */ |
| 59 | #define | |
| 44 | #define IntPoint(p) ((unsigned int)(lu_mem)(p)) | |
| 60 | 45 | |
| 61 | 46 | |
| 62 | 47 | |
| 63 | 48 | /* type to ensure maximum alignment */ |
| 64 | #if defined(LUAI_USER_ALIGNMENT_T) | |
| 65 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; | |
| 66 | #else | |
| 67 | typedef union { double u; void *s; lua_Integer i; long l; } L_Umaxalign; | |
| 49 | #if !defined(LUAI_USER_ALIGNMENT_T) | |
| 50 | #define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } | |
| 68 | 51 | #endif |
| 69 | 52 | |
| 53 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; | |
| 70 | 54 | |
| 71 | 55 | |
| 72 | /* | |
| 56 | /* result of a `usual argument conversion' over lua_Number */ | |
| 73 | 57 | typedef LUAI_UACNUMBER l_uacNumber; |
| 74 | typedef LUAI_UACINT l_uacInt; | |
| 75 | 58 | |
| 76 | 59 | |
| 77 | 60 | /* internal assertions for in-house debugging */ |
| r242899 | r242900 | |
| 88 | 71 | /* |
| 89 | 72 | ** assertion for checking API calls |
| 90 | 73 | */ |
| 74 | #if !defined(luai_apicheck) | |
| 75 | ||
| 91 | 76 | #if defined(LUA_USE_APICHECK) |
| 92 | 77 | #include <assert.h> |
| 93 | #define luai_apicheck(e) assert(e) | |
| 78 | #define luai_apicheck(L,e) assert(e) | |
| 94 | 79 | #else |
| 95 | #define luai_apicheck(e) lua_assert(e) | |
| 80 | #define luai_apicheck(L,e) lua_assert(e) | |
| 96 | 81 | #endif |
| 97 | 82 | |
| 83 | #endif | |
| 98 | 84 | |
| 99 | #define api_check(e,msg) luai_apicheck((e) && msg) | |
| 85 | #define api_check(l,e,msg) luai_apicheck(l,(e) && msg) | |
| 100 | 86 | |
| 101 | 87 | |
| 102 | 88 | #if !defined(UNUSED) |
| r242899 | r242900 | |
| 106 | 92 | |
| 107 | 93 | #define cast(t, exp) ((t)(exp)) |
| 108 | 94 | |
| 109 | #define cast_void(i) cast(void, (i)) | |
| 110 | 95 | #define cast_byte(i) cast(lu_byte, (i)) |
| 111 | 96 | #define cast_num(i) cast(lua_Number, (i)) |
| 112 | 97 | #define cast_int(i) cast(int, (i)) |
| 113 | 98 | #define cast_uchar(i) cast(unsigned char, (i)) |
| 114 | 99 | |
| 115 | 100 | |
| 116 | /* cast a signed lua_Integer to lua_Unsigned */ | |
| 117 | #if !defined(l_castS2U) | |
| 118 | #define l_castS2U(i) ((lua_Unsigned)(i)) | |
| 119 | #endif | |
| 120 | ||
| 121 | 101 | /* |
| 122 | ** cast a lua_Unsigned to a signed lua_Integer; this cast is | |
| 123 | ** not strict ISO C, but two-complement architectures should | |
| 124 | ** work fine. | |
| 125 | */ | |
| 126 | #if !defined(l_castU2S) | |
| 127 | #define l_castU2S(i) ((lua_Integer)(i)) | |
| 128 | #endif | |
| 129 | ||
| 130 | ||
| 131 | /* | |
| 132 | 102 | ** non-return type |
| 133 | 103 | */ |
| 134 | 104 | #if defined(__GNUC__) |
| 135 | 105 | #define l_noret void __attribute__((noreturn)) |
| 136 | #elif defined(_MSC_VER) | |
| 106 | #elif defined(_MSC_VER) | |
| 137 | 107 | #define l_noret void __declspec(noreturn) |
| 138 | 108 | #else |
| 139 | 109 | #define l_noret void |
| r242899 | r242900 | |
| 157 | 127 | |
| 158 | 128 | |
| 159 | 129 | /* |
| 160 | ** type for virtual-machine instructions | |
| 130 | ** type for virtual-machine instructions | |
| 161 | 131 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) |
| 162 | 132 | */ |
| 163 | #if LUAI_BITSINT >= 32 | |
| 164 | typedef unsigned int Instruction; | |
| 165 | #else | |
| 166 | typedef unsigned long Instruction; | |
| 167 | #endif | |
| 133 | typedef lu_int32 Instruction; | |
| 168 | 134 | |
| 169 | 135 | |
| 170 | 136 | |
| 137 | /* maximum stack for a Lua function */ | |
| 138 | #define MAXSTACK 250 | |
| 171 | 139 | |
| 140 | ||
| 141 | ||
| 172 | 142 | /* minimum size for the string table (must be power of 2) */ |
| 173 | 143 | #if !defined(MINSTRTABSIZE) |
| 174 | #define MINSTRTABSIZE | |
| 144 | #define MINSTRTABSIZE 32 | |
| 175 | 145 | #endif |
| 176 | 146 | |
| 177 | 147 | |
| r242899 | r242900 | |
| 182 | 152 | |
| 183 | 153 | |
| 184 | 154 | #if !defined(lua_lock) |
| 185 | #define lua_lock(L) ((void) 0) | |
| 186 | #define lua_unlock(L) ((void) 0) | |
| 155 | #define lua_lock(L) ((void) 0) | |
| 156 | #define lua_unlock(L) ((void) 0) | |
| 187 | 157 | #endif |
| 188 | 158 | |
| 189 | 159 | #if !defined(luai_threadyield) |
| 190 | #define luai_threadyield(L) | |
| 160 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} | |
| 191 | 161 | #endif |
| 192 | 162 | |
| 193 | 163 | |
| r242899 | r242900 | |
| 213 | 183 | #endif |
| 214 | 184 | |
| 215 | 185 | #if !defined(luai_userstateresume) |
| 216 | #define luai_userstateresume(L,n) | |
| 186 | #define luai_userstateresume(L,n) ((void)L) | |
| 217 | 187 | #endif |
| 218 | 188 | |
| 219 | 189 | #if !defined(luai_userstateyield) |
| 220 | #define luai_userstateyield(L,n) | |
| 190 | #define luai_userstateyield(L,n) ((void)L) | |
| 221 | 191 | #endif |
| 222 | 192 | |
| 193 | /* | |
| 194 | ** lua_number2int is a macro to convert lua_Number to int. | |
| 195 | ** lua_number2integer is a macro to convert lua_Number to lua_Integer. | |
| 196 | ** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. | |
| 197 | ** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. | |
| 198 | ** luai_hashnum is a macro to hash a lua_Number value into an integer. | |
| 199 | ** The hash must be deterministic and give reasonable values for | |
| 200 | ** both small and large values (outside the range of integers). | |
| 201 | */ | |
| 223 | 202 | |
| 203 | #if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ | |
| 204 | /* trick with Microsoft assembler for X86 */ | |
| 224 | 205 | |
| 206 | #define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} | |
| 207 | #define lua_number2integer(i,n) lua_number2int(i, n) | |
| 208 | #define lua_number2unsigned(i,n) \ | |
| 209 | {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} | |
| 210 | ||
| 211 | ||
| 212 | #elif defined(LUA_IEEE754TRICK) /* }{ */ | |
| 213 | /* the next trick should work on any machine using IEEE754 with | |
| 214 | a 32-bit int type */ | |
| 215 | ||
| 216 | union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; | |
| 217 | ||
| 218 | #if !defined(LUA_IEEEENDIAN) /* { */ | |
| 219 | #define LUAI_EXTRAIEEE \ | |
| 220 | static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; | |
| 221 | #define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) | |
| 222 | #else | |
| 223 | #define LUA_IEEEENDIANLOC LUA_IEEEENDIAN | |
| 224 | #define LUAI_EXTRAIEEE /* empty */ | |
| 225 | #endif /* } */ | |
| 226 | ||
| 227 | #define lua_number2int32(i,n,t) \ | |
| 228 | { LUAI_EXTRAIEEE \ | |
| 229 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ | |
| 230 | (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } | |
| 231 | ||
| 232 | #define luai_hashnum(i,n) \ | |
| 233 | { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ | |
| 234 | (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ | |
| 235 | ||
| 236 | #define lua_number2int(i,n) lua_number2int32(i, n, int) | |
| 237 | #define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) | |
| 238 | ||
| 239 | /* the trick can be expanded to lua_Integer when it is a 32-bit value */ | |
| 240 | #if defined(LUA_IEEELL) | |
| 241 | #define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) | |
| 242 | #endif | |
| 243 | ||
| 244 | #endif /* } */ | |
| 245 | ||
| 246 | ||
| 247 | /* the following definitions always work, but may be slow */ | |
| 248 | ||
| 249 | #if !defined(lua_number2int) | |
| 250 | #define lua_number2int(i,n) ((i)=(int)(n)) | |
| 251 | #endif | |
| 252 | ||
| 253 | #if !defined(lua_number2integer) | |
| 254 | #define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) | |
| 255 | #endif | |
| 256 | ||
| 257 | #if !defined(lua_number2unsigned) /* { */ | |
| 258 | /* the following definition assures proper modulo behavior */ | |
| 259 | #if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT) | |
| 260 | #include <math.h> | |
| 261 | #define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) | |
| 262 | #define lua_number2unsigned(i,n) \ | |
| 263 | ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) | |
| 264 | #else | |
| 265 | #define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) | |
| 266 | #endif | |
| 267 | #endif /* } */ | |
| 268 | ||
| 269 | ||
| 270 | #if !defined(lua_unsigned2number) | |
| 271 | /* on several machines, coercion from unsigned to double is slow, | |
| 272 | so it may be worth to avoid */ | |
| 273 | #define lua_unsigned2number(u) \ | |
| 274 | (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) | |
| 275 | #endif | |
| 276 | ||
| 277 | ||
| 278 | ||
| 279 | #if defined(ltable_c) && !defined(luai_hashnum) | |
| 280 | ||
| 281 | #include <float.h> | |
| 282 | #include <math.h> | |
| 283 | ||
| 284 | #define luai_hashnum(i,n) { int e; \ | |
| 285 | n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ | |
| 286 | lua_number2int(i, n); i += e; } | |
| 287 | ||
| 288 | #endif | |
| 289 | ||
| 290 | ||
| 291 | ||
| 225 | 292 | /* |
| 226 | 293 | ** macro to control inclusion of some hard tests on stack reallocation |
| 227 | 294 | */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lmathlib.c,v 1.11 | |
| 2 | ** $Id: lmathlib.c,v 1.83.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Standard mathematical library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lmathlib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <stdlib.h> |
| 14 | 9 | #include <math.h> |
| 15 | 10 | |
| 11 | #define lmathlib_c | |
| 12 | #define LUA_LIB | |
| 13 | ||
| 16 | 14 | #include "lua.h" |
| 17 | 15 | |
| 18 | 16 | #include "lauxlib.h" |
| r242899 | r242900 | |
| 20 | 18 | |
| 21 | 19 | |
| 22 | 20 | #undef PI |
| 23 | #define PI (l_mathop(3.141592653589793238462643383279502884)) | |
| 21 | #define PI ((lua_Number)(3.1415926535897932384626433832795)) | |
| 22 | #define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0)) | |
| 24 | 23 | |
| 25 | 24 | |
| 26 | #if !defined(l_rand) /* { */ | |
| 27 | #if defined(LUA_USE_POSIX) | |
| 28 | #define l_rand() random() | |
| 29 | #define l_srand(x) srandom(x) | |
| 30 | #define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */ | |
| 31 | #else | |
| 32 | #define l_rand() rand() | |
| 33 | #define l_srand(x) srand(x) | |
| 34 | #define L_RANDMAX RAND_MAX | |
| 35 | #endif | |
| 36 | #endif /* } */ | |
| 37 | 25 | |
| 38 | ||
| 39 | 26 | static int math_abs (lua_State *L) { |
| 40 | if (lua_isinteger(L, 1)) { | |
| 41 | lua_Integer n = lua_tointeger(L, 1); | |
| 42 | if (n < 0) n = (lua_Integer)(0u - n); | |
| 43 | lua_pushinteger(L, n); | |
| 44 | } | |
| 45 | else | |
| 46 | lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); | |
| 27 | lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); | |
| 47 | 28 | return 1; |
| 48 | 29 | } |
| 49 | 30 | |
| r242899 | r242900 | |
| 52 | 33 | return 1; |
| 53 | 34 | } |
| 54 | 35 | |
| 36 | static int math_sinh (lua_State *L) { | |
| 37 | lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); | |
| 38 | return 1; | |
| 39 | } | |
| 40 | ||
| 55 | 41 | static int math_cos (lua_State *L) { |
| 56 | 42 | lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); |
| 57 | 43 | return 1; |
| 58 | 44 | } |
| 59 | 45 | |
| 46 | static int math_cosh (lua_State *L) { | |
| 47 | lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); | |
| 48 | return 1; | |
| 49 | } | |
| 50 | ||
| 60 | 51 | static int math_tan (lua_State *L) { |
| 61 | 52 | lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); |
| 62 | 53 | return 1; |
| 63 | 54 | } |
| 64 | 55 | |
| 56 | static int math_tanh (lua_State *L) { | |
| 57 | lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); | |
| 58 | return 1; | |
| 59 | } | |
| 60 | ||
| 65 | 61 | static int math_asin (lua_State *L) { |
| 66 | 62 | lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); |
| 67 | 63 | return 1; |
| r242899 | r242900 | |
| 73 | 69 | } |
| 74 | 70 | |
| 75 | 71 | static int math_atan (lua_State *L) { |
| 76 | lua_Number y = luaL_checknumber(L, 1); | |
| 77 | lua_Number x = luaL_optnumber(L, 2, 1); | |
| 78 | lua_pushnumber(L, l_mathop(atan2)(y, x)); | |
| 72 | lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1))); | |
| 79 | 73 | return 1; |
| 80 | 74 | } |
| 81 | 75 | |
| 82 | ||
| 83 | static int math_toint (lua_State *L) { | |
| 84 | int valid; | |
| 85 | lua_Integer n = lua_tointegerx(L, 1, &valid); | |
| 86 | if (valid) | |
| 87 | lua_pushinteger(L, n); | |
| 88 | else { | |
| 89 | luaL_checkany(L, 1); | |
| 90 | lua_pushnil(L); /* value is not convertible to integer */ | |
| 91 | } | |
| 76 | static int math_atan2 (lua_State *L) { | |
| 77 | lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1), | |
| 78 | luaL_checknumber(L, 2))); | |
| 92 | 79 | return 1; |
| 93 | 80 | } |
| 94 | 81 | |
| 95 | ||
| 96 | static void pushnumint (lua_State *L, lua_Number d) { | |
| 97 | lua_Integer n; | |
| 98 | if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ | |
| 99 | lua_pushinteger(L, n); /* result is integer */ | |
| 100 | else | |
| 101 | lua_pushnumber(L, d); /* result is float */ | |
| 82 | static int math_ceil (lua_State *L) { | |
| 83 | lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1))); | |
| 84 | return 1; | |
| 102 | 85 | } |
| 103 | 86 | |
| 104 | ||
| 105 | 87 | static int math_floor (lua_State *L) { |
| 106 | if (lua_isinteger(L, 1)) | |
| 107 | lua_settop(L, 1); /* integer is its own floor */ | |
| 108 | else { | |
| 109 | lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); | |
| 110 | pushnumint(L, d); | |
| 111 | } | |
| 88 | lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1))); | |
| 112 | 89 | return 1; |
| 113 | 90 | } |
| 114 | 91 | |
| 115 | ||
| 116 | static int math_ceil (lua_State *L) { | |
| 117 | if (lua_isinteger(L, 1)) | |
| 118 | lua_settop(L, 1); /* integer is its own ceil */ | |
| 119 | else { | |
| 120 | lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); | |
| 121 | pushnumint(L, d); | |
| 122 | } | |
| 123 | return 1; | |
| 124 | } | |
| 125 | ||
| 126 | ||
| 127 | 92 | static int math_fmod (lua_State *L) { |
| 128 | if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { | |
| 129 | lua_Integer d = lua_tointeger(L, 2); | |
| 130 | if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ | |
| 131 | luaL_argcheck(L, d != 0, 2, "zero"); | |
| 132 | lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ | |
| 133 | } | |
| 134 | else | |
| 135 | lua_pushinteger(L, lua_tointeger(L, 1) % d); | |
| 136 | } | |
| 137 | else | |
| 138 | lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), | |
| 139 | luaL_checknumber(L, 2))); | |
| 93 | lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), | |
| 94 | luaL_checknumber(L, 2))); | |
| 140 | 95 | return 1; |
| 141 | 96 | } |
| 142 | 97 | |
| 143 | ||
| 144 | /* | |
| 145 | ** next function does not use 'modf', avoiding problems with 'double*' | |
| 146 | ** (which is not compatible with 'float*') when lua_Number is not | |
| 147 | ** 'double'. | |
| 148 | */ | |
| 149 | 98 | static int math_modf (lua_State *L) { |
| 150 | if (lua_isinteger(L ,1)) { | |
| 151 | lua_settop(L, 1); /* number is its own integer part */ | |
| 152 | lua_pushnumber(L, 0); /* no fractional part */ | |
| 153 | } | |
| 154 | else { | |
| 155 | lua_Number n = luaL_checknumber(L, 1); | |
| 156 | /* integer part (rounds toward zero) */ | |
| 157 | lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); | |
| 158 | pushnumint(L, ip); | |
| 159 | /* fractional part (test needed for inf/-inf) */ | |
| 160 | lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); | |
| 161 | } | |
| 99 | lua_Number ip; | |
| 100 | lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip); | |
| 101 | lua_pushnumber(L, ip); | |
| 102 | lua_pushnumber(L, fp); | |
| 162 | 103 | return 2; |
| 163 | 104 | } |
| 164 | 105 | |
| 165 | ||
| 166 | 106 | static int math_sqrt (lua_State *L) { |
| 167 | 107 | lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); |
| 168 | 108 | return 1; |
| 169 | 109 | } |
| 170 | 110 | |
| 171 | ||
| 172 | static int math_ult (lua_State *L) { | |
| 173 | lua_Integer a = luaL_checkinteger(L, 1); | |
| 174 | lua_Integer b = luaL_checkinteger(L, 2); | |
| 175 | lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); | |
| 111 | static int math_pow (lua_State *L) { | |
| 112 | lua_Number x = luaL_checknumber(L, 1); | |
| 113 | lua_Number y = luaL_checknumber(L, 2); | |
| 114 | lua_pushnumber(L, l_mathop(pow)(x, y)); | |
| 176 | 115 | return 1; |
| 177 | 116 | } |
| 178 | 117 | |
| r242899 | r242900 | |
| 183 | 122 | res = l_mathop(log)(x); |
| 184 | 123 | else { |
| 185 | 124 | lua_Number base = luaL_checknumber(L, 2); |
| 186 | if (base == 10.0) res = l_mathop(log10)(x); | |
| 125 | if (base == (lua_Number)10.0) res = l_mathop(log10)(x); | |
| 187 | 126 | else res = l_mathop(log)(x)/l_mathop(log)(base); |
| 188 | 127 | } |
| 189 | 128 | lua_pushnumber(L, res); |
| 190 | 129 | return 1; |
| 191 | 130 | } |
| 192 | 131 | |
| 132 | #if defined(LUA_COMPAT_LOG10) | |
| 133 | static int math_log10 (lua_State *L) { | |
| 134 | lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); | |
| 135 | return 1; | |
| 136 | } | |
| 137 | #endif | |
| 138 | ||
| 193 | 139 | static int math_exp (lua_State *L) { |
| 194 | 140 | lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); |
| 195 | 141 | return 1; |
| 196 | 142 | } |
| 197 | 143 | |
| 198 | 144 | static int math_deg (lua_State *L) { |
| 199 | lua_pushnumber(L, luaL_checknumber(L, 1) | |
| 145 | lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); | |
| 200 | 146 | return 1; |
| 201 | 147 | } |
| 202 | 148 | |
| 203 | 149 | static int math_rad (lua_State *L) { |
| 204 | lua_pushnumber(L, luaL_checknumber(L, 1) | |
| 150 | lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); | |
| 205 | 151 | return 1; |
| 206 | 152 | } |
| 207 | 153 | |
| 154 | static int math_frexp (lua_State *L) { | |
| 155 | int e; | |
| 156 | lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); | |
| 157 | lua_pushinteger(L, e); | |
| 158 | return 2; | |
| 159 | } | |
| 208 | 160 | |
| 161 | static int math_ldexp (lua_State *L) { | |
| 162 | lua_Number x = luaL_checknumber(L, 1); | |
| 163 | int ep = luaL_checkint(L, 2); | |
| 164 | lua_pushnumber(L, l_mathop(ldexp)(x, ep)); | |
| 165 | return 1; | |
| 166 | } | |
| 167 | ||
| 168 | ||
| 169 | ||
| 209 | 170 | static int math_min (lua_State *L) { |
| 210 | 171 | int n = lua_gettop(L); /* number of arguments */ |
| 211 | | |
| 172 | lua_Number dmin = luaL_checknumber(L, 1); | |
| 212 | 173 | int i; |
| 213 | luaL_argcheck(L, n >= 1, 1, "value expected"); | |
| 214 | for (i = 2; i <= n; i++) { | |
| 215 | if (lua_compare(L, i, imin, LUA_OPLT)) | |
| 216 | imin = i; | |
| 174 | for (i=2; i<=n; i++) { | |
| 175 | lua_Number d = luaL_checknumber(L, i); | |
| 176 | if (d < dmin) | |
| 177 | dmin = d; | |
| 217 | 178 | } |
| 218 | lua_push | |
| 179 | lua_pushnumber(L, dmin); | |
| 219 | 180 | return 1; |
| 220 | 181 | } |
| 221 | 182 | |
| 222 | 183 | |
| 223 | 184 | static int math_max (lua_State *L) { |
| 224 | 185 | int n = lua_gettop(L); /* number of arguments */ |
| 225 | | |
| 186 | lua_Number dmax = luaL_checknumber(L, 1); | |
| 226 | 187 | int i; |
| 227 | luaL_argcheck(L, n >= 1, 1, "value expected"); | |
| 228 | for (i = 2; i <= n; i++) { | |
| 229 | if (lua_compare(L, imax, i, LUA_OPLT)) | |
| 230 | imax = i; | |
| 188 | for (i=2; i<=n; i++) { | |
| 189 | lua_Number d = luaL_checknumber(L, i); | |
| 190 | if (d > dmax) | |
| 191 | dmax = d; | |
| 231 | 192 | } |
| 232 | lua_push | |
| 193 | lua_pushnumber(L, dmax); | |
| 233 | 194 | return 1; |
| 234 | 195 | } |
| 235 | 196 | |
| 236 | /* | |
| 237 | ** This function uses 'double' (instead of 'lua_Number') to ensure that | |
| 238 | ** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0' | |
| 239 | ** will keep full precision (ensuring that 'r' is always less than 1.0.) | |
| 240 | */ | |
| 197 | ||
| 241 | 198 | static int math_random (lua_State *L) { |
| 242 | lua_Integer low, up; | |
| 243 | double r = (double)(1.0 * l_rand()) * (1.0 / ((double)L_RANDMAX + 1.0)); | |
| 199 | /* the `%' avoids the (rare) case of r==1, and is needed also because on | |
| 200 | some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ | |
| 201 | lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; | |
| 244 | 202 | switch (lua_gettop(L)) { /* check number of arguments */ |
| 245 | 203 | case 0: { /* no arguments */ |
| 246 | lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */ | |
| 247 | return 1; | |
| 204 | lua_pushnumber(L, r); /* Number between 0 and 1 */ | |
| 205 | break; | |
| 248 | 206 | } |
| 249 | 207 | case 1: { /* only upper limit */ |
| 250 | low = 1; | |
| 251 | up = luaL_checkinteger(L, 1); | |
| 208 | lua_Number u = luaL_checknumber(L, 1); | |
| 209 | luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty"); | |
| 210 | lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */ | |
| 252 | 211 | break; |
| 253 | 212 | } |
| 254 | 213 | case 2: { /* lower and upper limits */ |
| 255 | low = luaL_checkinteger(L, 1); | |
| 256 | up = luaL_checkinteger(L, 2); | |
| 214 | lua_Number l = luaL_checknumber(L, 1); | |
| 215 | lua_Number u = luaL_checknumber(L, 2); | |
| 216 | luaL_argcheck(L, l <= u, 2, "interval is empty"); | |
| 217 | lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */ | |
| 257 | 218 | break; |
| 258 | 219 | } |
| 259 | 220 | default: return luaL_error(L, "wrong number of arguments"); |
| 260 | 221 | } |
| 261 | /* random integer in the interval [low, up] */ | |
| 262 | luaL_argcheck(L, low <= up, 1, "interval is empty"); | |
| 263 | luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, | |
| 264 | "interval too large"); | |
| 265 | r *= (double)(up - low) + 1.0; | |
| 266 | lua_pushinteger(L, (lua_Integer)r + low); | |
| 267 | 222 | return 1; |
| 268 | 223 | } |
| 269 | 224 | |
| 270 | 225 | |
| 271 | 226 | static int math_randomseed (lua_State *L) { |
| 272 | lua_Number seed = (lua_Number)luaL_checknumber(L, 1); | |
| 273 | l_srand((unsigned int)seed); | |
| 227 | srand(luaL_checkunsigned(L, 1)); | |
| 274 | 228 | (void)rand(); /* discard first value to avoid undesirable correlations */ |
| 275 | 229 | return 0; |
| 276 | 230 | } |
| 277 | 231 | |
| 278 | 232 | |
| 279 | static int math_type (lua_State *L) { | |
| 280 | if (lua_type(L, 1) == LUA_TNUMBER) { | |
| 281 | if (lua_isinteger(L, 1)) | |
| 282 | lua_pushliteral(L, "integer"); | |
| 283 | else | |
| 284 | lua_pushliteral(L, "float"); | |
| 285 | } | |
| 286 | else { | |
| 287 | luaL_checkany(L, 1); | |
| 288 | lua_pushnil(L); | |
| 289 | } | |
| 290 | return 1; | |
| 291 | } | |
| 292 | ||
| 293 | ||
| 294 | /* | |
| 295 | ** {================================================================== | |
| 296 | ** Deprecated functions (for compatibility only) | |
| 297 | ** =================================================================== | |
| 298 | */ | |
| 299 | #if defined(LUA_COMPAT_MATHLIB) | |
| 300 | ||
| 301 | static int math_cosh (lua_State *L) { | |
| 302 | lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); | |
| 303 | return 1; | |
| 304 | } | |
| 305 | ||
| 306 | static int math_sinh (lua_State *L) { | |
| 307 | lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); | |
| 308 | return 1; | |
| 309 | } | |
| 310 | ||
| 311 | static int math_tanh (lua_State *L) { | |
| 312 | lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); | |
| 313 | return 1; | |
| 314 | } | |
| 315 | ||
| 316 | static int math_pow (lua_State *L) { | |
| 317 | lua_Number x = luaL_checknumber(L, 1); | |
| 318 | lua_Number y = luaL_checknumber(L, 2); | |
| 319 | lua_pushnumber(L, l_mathop(pow)(x, y)); | |
| 320 | return 1; | |
| 321 | } | |
| 322 | ||
| 323 | static int math_frexp (lua_State *L) { | |
| 324 | int e; | |
| 325 | lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); | |
| 326 | lua_pushinteger(L, e); | |
| 327 | return 2; | |
| 328 | } | |
| 329 | ||
| 330 | static int math_ldexp (lua_State *L) { | |
| 331 | lua_Number x = luaL_checknumber(L, 1); | |
| 332 | int ep = (int)luaL_checkinteger(L, 2); | |
| 333 | lua_pushnumber(L, l_mathop(ldexp)(x, ep)); | |
| 334 | return 1; | |
| 335 | } | |
| 336 | ||
| 337 | static int math_log10 (lua_State *L) { | |
| 338 | lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); | |
| 339 | return 1; | |
| 340 | } | |
| 341 | ||
| 342 | #endif | |
| 343 | /* }================================================================== */ | |
| 344 | ||
| 345 | ||
| 346 | ||
| 347 | 233 | static const luaL_Reg mathlib[] = { |
| 348 | 234 | {"abs", math_abs}, |
| 349 | 235 | {"acos", math_acos}, |
| 350 | 236 | {"asin", math_asin}, |
| 237 | {"atan2", math_atan2}, | |
| 351 | 238 | {"atan", math_atan}, |
| 352 | 239 | {"ceil", math_ceil}, |
| 240 | {"cosh", math_cosh}, | |
| 353 | 241 | {"cos", math_cos}, |
| 354 | 242 | {"deg", math_deg}, |
| 355 | 243 | {"exp", math_exp}, |
| 356 | {"tointeger", math_toint}, | |
| 357 | 244 | {"floor", math_floor}, |
| 358 | 245 | {"fmod", math_fmod}, |
| 359 | {"ult", math_ult}, | |
| 246 | {"frexp", math_frexp}, | |
| 247 | {"ldexp", math_ldexp}, | |
| 248 | #if defined(LUA_COMPAT_LOG10) | |
| 249 | {"log10", math_log10}, | |
| 250 | #endif | |
| 360 | 251 | {"log", math_log}, |
| 361 | 252 | {"max", math_max}, |
| 362 | 253 | {"min", math_min}, |
| 363 | 254 | {"modf", math_modf}, |
| 255 | {"pow", math_pow}, | |
| 364 | 256 | {"rad", math_rad}, |
| 365 | 257 | {"random", math_random}, |
| 366 | 258 | {"randomseed", math_randomseed}, |
| 259 | {"sinh", math_sinh}, | |
| 367 | 260 | {"sin", math_sin}, |
| 368 | 261 | {"sqrt", math_sqrt}, |
| 369 | {"tan", math_tan}, | |
| 370 | {"type", math_type}, | |
| 371 | #if defined(LUA_COMPAT_MATHLIB) | |
| 372 | {"atan2", math_atan}, | |
| 373 | {"cosh", math_cosh}, | |
| 374 | {"sinh", math_sinh}, | |
| 375 | 262 | {"tanh", math_tanh}, |
| 376 | {"pow", math_pow}, | |
| 377 | {"frexp", math_frexp}, | |
| 378 | {"ldexp", math_ldexp}, | |
| 379 | {"log10", math_log10}, | |
| 380 | #endif | |
| 381 | /* placeholders */ | |
| 382 | {"pi", NULL}, | |
| 383 | {"huge", NULL}, | |
| 384 | {"maxinteger", NULL}, | |
| 385 | {"mininteger", NULL}, | |
| 263 | {"tan", math_tan}, | |
| 386 | 264 | {NULL, NULL} |
| 387 | 265 | }; |
| 388 | 266 | |
| r242899 | r242900 | |
| 394 | 272 | luaL_newlib(L, mathlib); |
| 395 | 273 | lua_pushnumber(L, PI); |
| 396 | 274 | lua_setfield(L, -2, "pi"); |
| 397 | lua_pushnumber(L, | |
| 275 | lua_pushnumber(L, HUGE_VAL); | |
| 398 | 276 | lua_setfield(L, -2, "huge"); |
| 399 | lua_pushinteger(L, LUA_MAXINTEGER); | |
| 400 | lua_setfield(L, -2, "maxinteger"); | |
| 401 | lua_pushinteger(L, LUA_MININTEGER); | |
| 402 | lua_setfield(L, -2, "mininteger"); | |
| 403 | 277 | return 1; |
| 404 | 278 | } |
| 405 | 279 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lmem.c,v 1.8 | |
| 2 | ** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Interface to Memory Manager |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | ||
| 8 | #include <stddef.h> | |
| 9 | ||
| 7 | 10 | #define lmem_c |
| 8 | 11 | #define LUA_CORE |
| 9 | 12 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <stddef.h> | |
| 14 | ||
| 15 | 13 | #include "lua.h" |
| 16 | 14 | |
| 17 | 15 | #include "ldebug.h" |
| r242899 | r242900 | |
| 26 | 24 | /* |
| 27 | 25 | ** About the realloc function: |
| 28 | 26 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); |
| 29 | ** ( | |
| 27 | ** (`osize' is the old size, `nsize' is the new size) | |
| 30 | 28 | ** |
| 31 | ** * frealloc(ud, NULL, x, s) creates a new block of size | |
| 29 | ** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no | |
| 32 | 30 | ** matter 'x'). |
| 33 | 31 | ** |
| 34 | ** * frealloc(ud, p, x, 0) frees the block | |
| 32 | ** * frealloc(ud, p, x, 0) frees the block `p' | |
| 35 | 33 | ** (in this specific case, frealloc must return NULL); |
| 36 | 34 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing |
| 37 | ** (which is equivalent to free(NULL) in | |
| 35 | ** (which is equivalent to free(NULL) in ANSI C) | |
| 38 | 36 | ** |
| 39 | 37 | ** frealloc returns NULL if it cannot create or reallocate the area |
| 40 | 38 | ** (any reallocation to an equal or smaller size cannot fail!) |
| r242899 | r242900 | |
| 85 | 83 | #endif |
| 86 | 84 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); |
| 87 | 85 | if (newblock == NULL && nsize > 0) { |
| 88 | api_check( nsize > realosize, | |
| 86 | api_check(L, nsize > realosize, | |
| 89 | 87 | "realloc cannot fail when shrinking a block"); |
| 90 | luaC_fullgc(L, 1); /* try to free some memory... */ | |
| 91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ | |
| 88 | if (g->gcrunning) { | |
| 89 | luaC_fullgc(L, 1); /* try to free some memory... */ | |
| 90 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ | |
| 91 | } | |
| 92 | 92 | if (newblock == NULL) |
| 93 | 93 | luaD_throw(L, LUA_ERRMEM); |
| 94 | 94 | } |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lmem.h,v 1.4 | |
| 2 | ** $Id: lmem.h,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Interface to Memory Manager |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 15 | 15 | |
| 16 | 16 | |
| 17 | 17 | /* |
| 18 | ** This macro reallocs a vector 'b' from 'on' to 'n' elements, where | |
| 19 | ** each element has size 'e'. In case of arithmetic overflow of the | |
| 20 | ** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because | |
| 21 | ** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e). | |
| 22 | ** | |
| 23 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' | |
| 24 | ** comparison avoids a runtime comparison when overflow cannot occur. | |
| 25 | ** The compiler should be able to optimize the real test by itself, but | |
| 26 | ** when it does it, it may give a warning about "comparison is always | |
| 27 | ** false due to limited range of data type"; the +1 tricks the compiler, | |
| 28 | ** avoiding this warning but also this optimization.) | |
| 18 | ** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is | |
| 19 | ** always constant. | |
| 20 | ** The macro is somewhat complex to avoid warnings: | |
| 21 | ** +1 avoids warnings of "comparison has constant result"; | |
| 22 | ** cast to 'void' avoids warnings of "value unused". | |
| 29 | 23 | */ |
| 30 | 24 | #define luaM_reallocv(L,b,on,n,e) \ |
| 31 | (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ | |
| 32 | ? luaM_toobig(L) : cast_void(0)) , \ | |
| 25 | (cast(void, \ | |
| 26 | (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \ | |
| 33 | 27 | luaM_realloc_(L, (b), (on)*(e), (n)*(e))) |
| 34 | 28 | |
| 35 | /* | |
| 36 | ** Arrays of chars do not need any test | |
| 37 | */ | |
| 38 | #define luaM_reallocvchar(L,b,on,n) \ | |
| 39 | cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) | |
| 40 | ||
| 41 | 29 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) |
| 42 | 30 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) |
| 43 | #define luaM_freearray(L, b, n) luaM_realloc | |
| 31 | #define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) | |
| 44 | 32 | |
| 45 | 33 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) |
| 46 | 34 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: loadlib.c,v 1.1 | |
| 2 | ** $Id: loadlib.c,v 1.111.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Dynamic library loader for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | ** |
| r242899 | r242900 | |
| 8 | 8 | ** systems. |
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | #define loadlib_c | |
| 12 | #define LUA_LIB | |
| 13 | 11 | |
| 14 | #include "lprefix.h" | |
| 12 | /* | |
| 13 | ** if needed, includes windows header before everything else | |
| 14 | */ | |
| 15 | #if defined(_WIN32) | |
| 16 | #include <windows.h> | |
| 17 | #endif | |
| 15 | 18 | |
| 16 | 19 | |
| 17 | 20 | #include <stdlib.h> |
| 18 | 21 | #include <string.h> |
| 19 | 22 | |
| 23 | ||
| 24 | #define loadlib_c | |
| 25 | #define LUA_LIB | |
| 26 | ||
| 20 | 27 | #include "lua.h" |
| 21 | 28 | |
| 22 | 29 | #include "lauxlib.h" |
| r242899 | r242900 | |
| 24 | 31 | |
| 25 | 32 | |
| 26 | 33 | /* |
| 27 | ** LUA_PATH | |
| 34 | ** LUA_PATH and LUA_CPATH are the names of the environment | |
| 28 | 35 | ** variables that Lua check to set its paths. |
| 29 | 36 | */ |
| 30 | #if !defined(LUA_PATH_VAR) | |
| 31 | #define LUA_PATH_VAR "LUA_PATH" | |
| 37 | #if !defined(LUA_PATH) | |
| 38 | #define LUA_PATH "LUA_PATH" | |
| 32 | 39 | #endif |
| 33 | 40 | |
| 34 | #if !defined(LUA_CPATH_VAR) | |
| 35 | #define LUA_CPATH_VAR "LUA_CPATH" | |
| 41 | #if !defined(LUA_CPATH) | |
| 42 | #define LUA_CPATH "LUA_CPATH" | |
| 36 | 43 | #endif |
| 37 | 44 | |
| 38 | 45 | #define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR |
| 39 | 46 | |
| 40 | #define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX | |
| 41 | #define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX | |
| 47 | #define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX | |
| 48 | #define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX | |
| 42 | 49 | |
| 43 | 50 | /* |
| 44 | 51 | ** LUA_PATH_SEP is the character that separates templates in a path. |
| r242899 | r242900 | |
| 85 | 92 | #define LUA_OFSEP "_" |
| 86 | 93 | |
| 87 | 94 | |
| 88 | /* | |
| 89 | ** unique key for table in the registry that keeps handles | |
| 90 | ** for all loaded C libraries | |
| 91 | */ | |
| 92 | static const int CLIBS = 0; | |
| 95 | /* table (in the registry) that keeps handles for all loaded C libraries */ | |
| 96 | #define CLIBS "_CLIBS" | |
| 93 | 97 | |
| 94 | 98 | #define LIB_FAIL "open" |
| 95 | 99 | |
| 100 | ||
| 101 | /* error codes for ll_loadfunc */ | |
| 102 | #define ERRLIB 1 | |
| 103 | #define ERRFUNC 2 | |
| 104 | ||
| 96 | 105 | #define setprogdir(L) ((void)0) |
| 97 | 106 | |
| 98 | 107 | |
| 99 | 108 | /* |
| 100 | 109 | ** system-dependent functions |
| 101 | 110 | */ |
| 111 | static void ll_unloadlib (void *lib); | |
| 112 | static void *ll_load (lua_State *L, const char *path, int seeglb); | |
| 113 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); | |
| 102 | 114 | |
| 103 | /* | |
| 104 | ** unload library 'lib' | |
| 105 | */ | |
| 106 | static void lsys_unloadlib (void *lib); | |
| 107 | 115 | |
| 108 | /* | |
| 109 | ** load C library in file 'path'. If 'seeglb', load with all names in | |
| 110 | ** the library global. | |
| 111 | ** Returns the library; in case of error, returns NULL plus an | |
| 112 | ** error string in the stack. | |
| 113 | */ | |
| 114 | static void *lsys_load (lua_State *L, const char *path, int seeglb); | |
| 115 | 116 | |
| 117 | #if defined(LUA_USE_DLOPEN) | |
| 116 | 118 | /* |
| 117 | ** Try to find a function named 'sym' in library 'lib'. | |
| 118 | ** Returns the function; in case of error, returns NULL plus an | |
| 119 | ** error string in the stack. | |
| 120 | */ | |
| 121 | static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym); | |
| 122 | ||
| 123 | ||
| 124 | ||
| 125 | ||
| 126 | #if defined(LUA_USE_DLOPEN) /* { */ | |
| 127 | /* | |
| 128 | 119 | ** {======================================================================== |
| 129 | 120 | ** This is an implementation of loadlib based on the dlfcn interface. |
| 130 | 121 | ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, |
| r242899 | r242900 | |
| 135 | 126 | |
| 136 | 127 | #include <dlfcn.h> |
| 137 | 128 | |
| 138 | /* | |
| 139 | ** Macro to covert pointer to void* to pointer to function. This cast | |
| 140 | ** is undefined according to ISO C, but POSIX assumes that it must work. | |
| 141 | ** (The '__extension__' in gnu compilers is only to avoid warnings.) | |
| 142 | */ | |
| 143 | #if defined(__GNUC__) | |
| 144 | #define cast_func(p) (__extension__ (lua_CFunction)(p)) | |
| 145 | #else | |
| 146 | #define cast_func(p) ((lua_CFunction)(p)) | |
| 147 | #endif | |
| 148 | ||
| 149 | ||
| 150 | static void lsys_unloadlib (void *lib) { | |
| 129 | static void ll_unloadlib (void *lib) { | |
| 151 | 130 | dlclose(lib); |
| 152 | 131 | } |
| 153 | 132 | |
| 154 | 133 | |
| 155 | static void *l | |
| 134 | static void *ll_load (lua_State *L, const char *path, int seeglb) { | |
| 156 | 135 | void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); |
| 157 | 136 | if (lib == NULL) lua_pushstring(L, dlerror()); |
| 158 | 137 | return lib; |
| 159 | 138 | } |
| 160 | 139 | |
| 161 | 140 | |
| 162 | static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { | |
| 163 | lua_CFunction f = cast_func(dlsym(lib, sym)); | |
| 141 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { | |
| 142 | lua_CFunction f = (lua_CFunction)dlsym(lib, sym); | |
| 164 | 143 | if (f == NULL) lua_pushstring(L, dlerror()); |
| 165 | 144 | return f; |
| 166 | 145 | } |
| r242899 | r242900 | |
| 169 | 148 | |
| 170 | 149 | |
| 171 | 150 | |
| 172 | #elif defined(LUA_DL_DLL) | |
| 151 | #elif defined(LUA_DL_DLL) | |
| 173 | 152 | /* |
| 174 | 153 | ** {====================================================================== |
| 175 | 154 | ** This is an implementation of loadlib for Windows using native functions. |
| 176 | 155 | ** ======================================================================= |
| 177 | 156 | */ |
| 178 | 157 | |
| 179 | #include <windows.h> | |
| 180 | ||
| 181 | 158 | #undef setprogdir |
| 182 | 159 | |
| 183 | 160 | /* |
| r242899 | r242900 | |
| 213 | 190 | lua_pushfstring(L, "system error %d\n", error); |
| 214 | 191 | } |
| 215 | 192 | |
| 216 | static void l | |
| 193 | static void ll_unloadlib (void *lib) { | |
| 217 | 194 | FreeLibrary((HMODULE)lib); |
| 218 | 195 | } |
| 219 | 196 | |
| 220 | 197 | |
| 221 | static void *l | |
| 198 | static void *ll_load (lua_State *L, const char *path, int seeglb) { | |
| 222 | 199 | HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); |
| 223 | 200 | (void)(seeglb); /* not used: symbols are 'global' by default */ |
| 224 | 201 | if (lib == NULL) pusherror(L); |
| r242899 | r242900 | |
| 226 | 203 | } |
| 227 | 204 | |
| 228 | 205 | |
| 229 | static lua_CFunction l | |
| 206 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { | |
| 230 | 207 | lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); |
| 231 | 208 | if (f == NULL) pusherror(L); |
| 232 | 209 | return f; |
| r242899 | r242900 | |
| 235 | 212 | /* }====================================================== */ |
| 236 | 213 | |
| 237 | 214 | |
| 238 | #else | |
| 215 | #else | |
| 239 | 216 | /* |
| 240 | 217 | ** {====================================================== |
| 241 | 218 | ** Fallback for other systems |
| r242899 | r242900 | |
| 249 | 226 | #define DLMSG "dynamic libraries not enabled; check your Lua installation" |
| 250 | 227 | |
| 251 | 228 | |
| 252 | static void l | |
| 229 | static void ll_unloadlib (void *lib) { | |
| 253 | 230 | (void)(lib); /* not used */ |
| 254 | 231 | } |
| 255 | 232 | |
| 256 | 233 | |
| 257 | static void *l | |
| 234 | static void *ll_load (lua_State *L, const char *path, int seeglb) { | |
| 258 | 235 | (void)(path); (void)(seeglb); /* not used */ |
| 259 | 236 | lua_pushliteral(L, DLMSG); |
| 260 | 237 | return NULL; |
| 261 | 238 | } |
| 262 | 239 | |
| 263 | 240 | |
| 264 | static lua_CFunction l | |
| 241 | static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { | |
| 265 | 242 | (void)(lib); (void)(sym); /* not used */ |
| 266 | 243 | lua_pushliteral(L, DLMSG); |
| 267 | 244 | return NULL; |
| 268 | 245 | } |
| 269 | 246 | |
| 270 | 247 | /* }====================================================== */ |
| 271 | #endif | |
| 248 | #endif | |
| 272 | 249 | |
| 273 | 250 | |
| 274 | /* | |
| 275 | ** return registry.CLIBS[path] | |
| 276 | */ | |
| 277 | static void *checkclib (lua_State *L, const char *path) { | |
| 251 | static void *ll_checkclib (lua_State *L, const char *path) { | |
| 278 | 252 | void *plib; |
| 279 | lua_ | |
| 253 | lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); | |
| 280 | 254 | lua_getfield(L, -1, path); |
| 281 | 255 | plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ |
| 282 | 256 | lua_pop(L, 2); /* pop CLIBS table and 'plib' */ |
| r242899 | r242900 | |
| 284 | 258 | } |
| 285 | 259 | |
| 286 | 260 | |
| 287 | /* | |
| 288 | ** registry.CLIBS[path] = plib -- for queries | |
| 289 | ** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries | |
| 290 | */ | |
| 291 | static void addtoclib (lua_State *L, const char *path, void *plib) { | |
| 292 | lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS); | |
| 261 | static void ll_addtoclib (lua_State *L, const char *path, void *plib) { | |
| 262 | lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); | |
| 293 | 263 | lua_pushlightuserdata(L, plib); |
| 294 | 264 | lua_pushvalue(L, -1); |
| 295 | 265 | lua_setfield(L, -3, path); /* CLIBS[path] = plib */ |
| r242899 | r242900 | |
| 299 | 269 | |
| 300 | 270 | |
| 301 | 271 | /* |
| 302 | ** __gc tag method for CLIBS table: calls 'l | |
| 272 | ** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib | |
| 303 | 273 | ** handles in list CLIBS |
| 304 | 274 | */ |
| 305 | 275 | static int gctm (lua_State *L) { |
| 306 | | |
| 276 | int n = luaL_len(L, 1); | |
| 307 | 277 | for (; n >= 1; n--) { /* for each handle, in reverse order */ |
| 308 | 278 | lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ |
| 309 | l | |
| 279 | ll_unloadlib(lua_touserdata(L, -1)); | |
| 310 | 280 | lua_pop(L, 1); /* pop handle */ |
| 311 | 281 | } |
| 312 | 282 | return 0; |
| 313 | 283 | } |
| 314 | 284 | |
| 315 | 285 | |
| 316 | ||
| 317 | /* error codes for 'lookforfunc' */ | |
| 318 | #define ERRLIB 1 | |
| 319 | #define ERRFUNC 2 | |
| 320 | ||
| 321 | /* | |
| 322 | ** Look for a C function named 'sym' in a dynamically loaded library | |
| 323 | ** 'path'. | |
| 324 | ** First, check whether the library is already loaded; if not, try | |
| 325 | ** to load it. | |
| 326 | ** Then, if 'sym' is '*', return true (as library has been loaded). | |
| 327 | ** Otherwise, look for symbol 'sym' in the library and push a | |
| 328 | ** C function with that symbol. | |
| 329 | ** Return 0 and 'true' or a function in the stack; in case of | |
| 330 | ** errors, return an error code and an error message in the stack. | |
| 331 | */ | |
| 332 | static int lookforfunc (lua_State *L, const char *path, const char *sym) { | |
| 333 | void *reg = checkclib(L, path); /* check loaded C libraries */ | |
| 286 | static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { | |
| 287 | void *reg = ll_checkclib(L, path); /* check loaded C libraries */ | |
| 334 | 288 | if (reg == NULL) { /* must load library? */ |
| 335 | reg = l | |
| 289 | reg = ll_load(L, path, *sym == '*'); | |
| 336 | 290 | if (reg == NULL) return ERRLIB; /* unable to load library */ |
| 337 | addtoclib(L, path, reg); | |
| 291 | ll_addtoclib(L, path, reg); | |
| 338 | 292 | } |
| 339 | 293 | if (*sym == '*') { /* loading only library (no function)? */ |
| 340 | 294 | lua_pushboolean(L, 1); /* return 'true' */ |
| 341 | 295 | return 0; /* no errors */ |
| 342 | 296 | } |
| 343 | 297 | else { |
| 344 | lua_CFunction f = l | |
| 298 | lua_CFunction f = ll_sym(L, reg, sym); | |
| 345 | 299 | if (f == NULL) |
| 346 | 300 | return ERRFUNC; /* unable to find function */ |
| 347 | 301 | lua_pushcfunction(L, f); /* else create new function */ |
| r242899 | r242900 | |
| 353 | 307 | static int ll_loadlib (lua_State *L) { |
| 354 | 308 | const char *path = luaL_checkstring(L, 1); |
| 355 | 309 | const char *init = luaL_checkstring(L, 2); |
| 356 | int stat = lo | |
| 310 | int stat = ll_loadfunc(L, path, init); | |
| 357 | 311 | if (stat == 0) /* no errors? */ |
| 358 | 312 | return 1; /* return the loaded function */ |
| 359 | 313 | else { /* error; error message is on stack top */ |
| r242899 | r242900 | |
| 406 | 360 | lua_remove(L, -2); /* remove path template */ |
| 407 | 361 | if (readable(filename)) /* does file exist and is readable? */ |
| 408 | 362 | return filename; /* return that file name */ |
| 409 | lua_pushfstring(L, "\n\tno file | |
| 363 | lua_pushfstring(L, "\n\tno file " LUA_QS, filename); | |
| 410 | 364 | lua_remove(L, -2); /* remove file name */ |
| 411 | 365 | luaL_addvalue(&msg); /* concatenate error msg. entry */ |
| 412 | 366 | } |
| r242899 | r242900 | |
| 436 | 390 | lua_getfield(L, lua_upvalueindex(1), pname); |
| 437 | 391 | path = lua_tostring(L, -1); |
| 438 | 392 | if (path == NULL) |
| 439 | luaL_error(L, " | |
| 393 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); | |
| 440 | 394 | return searchpath(L, name, path, ".", dirsep); |
| 441 | 395 | } |
| 442 | 396 | |
| r242899 | r242900 | |
| 447 | 401 | return 2; /* return open function and file name */ |
| 448 | 402 | } |
| 449 | 403 | else |
| 450 | return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s", | |
| 404 | return luaL_error(L, "error loading module " LUA_QS | |
| 405 | " from file " LUA_QS ":\n\t%s", | |
| 451 | 406 | lua_tostring(L, 1), filename, lua_tostring(L, -1)); |
| 452 | 407 | } |
| 453 | 408 | |
| r242899 | r242900 | |
| 461 | 416 | } |
| 462 | 417 | |
| 463 | 418 | |
| 464 | /* | |
| 465 | ** Try to find a load function for module 'modname' at file 'filename'. | |
| 466 | ** First, change '.' to '_' in 'modname'; then, if 'modname' has | |
| 467 | ** the form X-Y (that is, it has an "ignore mark"), build a function | |
| 468 | ** name "luaopen_X" and look for it. (For compatibility, if that | |
| 469 | ** fails, it also tries "luaopen_Y".) If there is no ignore mark, | |
| 470 | ** look for a function named "luaopen_modname". | |
| 471 | */ | |
| 472 | 419 | static int loadfunc (lua_State *L, const char *filename, const char *modname) { |
| 473 | const char * | |
| 420 | const char *funcname; | |
| 474 | 421 | const char *mark; |
| 475 | 422 | modname = luaL_gsub(L, modname, ".", LUA_OFSEP); |
| 476 | 423 | mark = strchr(modname, *LUA_IGMARK); |
| 477 | 424 | if (mark) { |
| 478 | 425 | int stat; |
| 479 | openfunc = lua_pushlstring(L, modname, mark - modname); | |
| 480 | openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc); | |
| 481 | stat = lookforfunc(L, filename, openfunc); | |
| 426 | funcname = lua_pushlstring(L, modname, mark - modname); | |
| 427 | funcname = lua_pushfstring(L, LUA_POF"%s", funcname); | |
| 428 | stat = ll_loadfunc(L, filename, funcname); | |
| 482 | 429 | if (stat != ERRFUNC) return stat; |
| 483 | 430 | modname = mark + 1; /* else go ahead and try old-style name */ |
| 484 | 431 | } |
| 485 | openfunc = lua_pushfstring(L, LUA_POF"%s", modname); | |
| 486 | return lookforfunc(L, filename, openfunc); | |
| 432 | funcname = lua_pushfstring(L, LUA_POF"%s", modname); | |
| 433 | return ll_loadfunc(L, filename, funcname); | |
| 487 | 434 | } |
| 488 | 435 | |
| 489 | 436 | |
| r242899 | r242900 | |
| 508 | 455 | if (stat != ERRFUNC) |
| 509 | 456 | return checkload(L, 0, filename); /* real error */ |
| 510 | 457 | else { /* open function not found */ |
| 511 | lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename); | |
| 458 | lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, | |
| 459 | name, filename); | |
| 512 | 460 | return 1; |
| 513 | 461 | } |
| 514 | 462 | } |
| r242899 | r242900 | |
| 520 | 468 | static int searcher_preload (lua_State *L) { |
| 521 | 469 | const char *name = luaL_checkstring(L, 1); |
| 522 | 470 | lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); |
| 523 | if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */ | |
| 471 | lua_getfield(L, -1, name); | |
| 472 | if (lua_isnil(L, -1)) /* not found? */ | |
| 524 | 473 | lua_pushfstring(L, "\n\tno field package.preload['%s']", name); |
| 525 | 474 | return 1; |
| 526 | 475 | } |
| r242899 | r242900 | |
| 530 | 479 | int i; |
| 531 | 480 | luaL_Buffer msg; /* to build error message */ |
| 532 | 481 | luaL_buffinit(L, &msg); |
| 533 | /* push 'package.searchers' to index 3 in the stack */ | |
| 534 | if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE) | |
| 535 | luaL_error(L, "'package.searchers' must be a table"); | |
| 482 | lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ | |
| 483 | if (!lua_istable(L, 3)) | |
| 484 | luaL_error(L, LUA_QL("package.searchers") " must be a table"); | |
| 536 | 485 | /* iterate over available searchers to find a loader */ |
| 537 | 486 | for (i = 1; ; i++) { |
| 538 | if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */ | |
| 487 | lua_rawgeti(L, 3, i); /* get a searcher */ | |
| 488 | if (lua_isnil(L, -1)) { /* no more searchers? */ | |
| 539 | 489 | lua_pop(L, 1); /* remove nil */ |
| 540 | 490 | luaL_pushresult(&msg); /* create error message */ |
| 541 | luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1)); | |
| 491 | luaL_error(L, "module " LUA_QS " not found:%s", | |
| 492 | name, lua_tostring(L, -1)); | |
| 542 | 493 | } |
| 543 | 494 | lua_pushstring(L, name); |
| 544 | 495 | lua_call(L, 1, 2); /* call it */ |
| r242899 | r242900 | |
| 569 | 520 | lua_call(L, 2, 1); /* run loader to load module */ |
| 570 | 521 | if (!lua_isnil(L, -1)) /* non-nil return? */ |
| 571 | 522 | lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ |
| 572 | if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ | |
| 523 | lua_getfield(L, 2, name); | |
| 524 | if (lua_isnil(L, -1)) { /* module did not set a value? */ | |
| 573 | 525 | lua_pushboolean(L, 1); /* use true as result */ |
| 574 | 526 | lua_pushvalue(L, -1); /* extra copy to be returned */ |
| 575 | 527 | lua_setfield(L, 2, name); /* _LOADED[name] = true */ |
| r242899 | r242900 | |
| 596 | 548 | if (lua_getstack(L, 1, &ar) == 0 || |
| 597 | 549 | lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ |
| 598 | 550 | lua_iscfunction(L, -1)) |
| 599 | luaL_error(L, " | |
| 551 | luaL_error(L, LUA_QL("module") " not called from a Lua function"); | |
| 600 | 552 | lua_pushvalue(L, -2); /* copy new environment table to top */ |
| 601 | 553 | lua_setupvalue(L, -2, 1); |
| 602 | 554 | lua_pop(L, 1); /* remove function */ |
| r242899 | r242900 | |
| 635 | 587 | int lastarg = lua_gettop(L); /* last parameter */ |
| 636 | 588 | luaL_pushmodule(L, modname, 1); /* get/create module table */ |
| 637 | 589 | /* check whether table already has a _NAME field */ |
| 638 | if (lua_getfield(L, -1, "_NAME") != LUA_TNIL) | |
| 639 | lua_pop(L, 1); /* table is an initialized module */ | |
| 590 | lua_getfield(L, -1, "_NAME"); | |
| 591 | if (!lua_isnil(L, -1)) /* is table an initialized module? */ | |
| 592 | lua_pop(L, 1); | |
| 640 | 593 | else { /* no; initialize it */ |
| 641 | 594 | lua_pop(L, 1); |
| 642 | 595 | modinit(L, modname); |
| r242899 | r242900 | |
| 706 | 659 | #if defined(LUA_COMPAT_MODULE) |
| 707 | 660 | {"seeall", ll_seeall}, |
| 708 | 661 | #endif |
| 709 | /* placeholders */ | |
| 710 | {"preload", NULL}, | |
| 711 | {"cpath", NULL}, | |
| 712 | {"path", NULL}, | |
| 713 | {"searchers", NULL}, | |
| 714 | {"loaded", NULL}, | |
| 715 | 662 | {NULL, NULL} |
| 716 | 663 | }; |
| 717 | 664 | |
| r242899 | r242900 | |
| 737 | 684 | lua_pushcclosure(L, searchers[i], 1); |
| 738 | 685 | lua_rawseti(L, -2, i+1); |
| 739 | 686 | } |
| 740 | #if defined(LUA_COMPAT_LOADERS) | |
| 741 | lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ | |
| 742 | lua_setfield(L, -3, "loaders"); /* put it in field 'loaders' */ | |
| 743 | #endif | |
| 744 | lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ | |
| 745 | 687 | } |
| 746 | 688 | |
| 747 | 689 | |
| 748 | /* | |
| 749 | ** create table CLIBS to keep track of loaded C libraries, | |
| 750 | ** setting a finalizer to close all libraries when closing state. | |
| 751 | */ | |
| 752 | static void createclibstable (lua_State *L) { | |
| 753 | lua_newtable(L); /* create CLIBS table */ | |
| 754 | lua_createtable(L, 0, 1); /* create metatable for CLIBS */ | |
| 690 | LUAMOD_API int luaopen_package (lua_State *L) { | |
| 691 | /* create table CLIBS to keep track of loaded C libraries */ | |
| 692 | luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); | |
| 693 | lua_createtable(L, 0, 1); /* metatable for CLIBS */ | |
| 755 | 694 | lua_pushcfunction(L, gctm); |
| 756 | 695 | lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ |
| 757 | 696 | lua_setmetatable(L, -2); |
| 758 | lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS); /* set CLIBS table in registry */ | |
| 759 | } | |
| 760 | ||
| 761 | ||
| 762 | LUAMOD_API int luaopen_package (lua_State *L) { | |
| 763 | createclibstable(L); | |
| 764 | luaL_newlib(L, pk_funcs); /* create 'package' table */ | |
| 697 | /* create `package' table */ | |
| 698 | luaL_newlib(L, pk_funcs); | |
| 765 | 699 | createsearcherstable(L); |
| 700 | #if defined(LUA_COMPAT_LOADERS) | |
| 701 | lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ | |
| 702 | lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ | |
| 703 | #endif | |
| 704 | lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ | |
| 766 | 705 | /* set field 'path' */ |
| 767 | setpath(L, "path", LUA_PATHV | |
| 706 | setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); | |
| 768 | 707 | /* set field 'cpath' */ |
| 769 | setpath(L, "cpath", LUA_CPATHV | |
| 708 | setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); | |
| 770 | 709 | /* store config information */ |
| 771 | 710 | lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" |
| 772 | 711 | LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); |
| 773 | 712 | lua_setfield(L, -2, "config"); |
| 774 | /* set field | |
| 713 | /* set field `loaded' */ | |
| 775 | 714 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); |
| 776 | 715 | lua_setfield(L, -2, "loaded"); |
| 777 | /* set field | |
| 716 | /* set field `preload' */ | |
| 778 | 717 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); |
| 779 | 718 | lua_setfield(L, -2, "preload"); |
| 780 | 719 | lua_pushglobaltable(L); |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.1 | |
| 2 | ** $Id: lobject.c,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Some generic functions over Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lobject_c | |
| 8 | #define LUA_CORE | |
| 9 | ||
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 7 | #include <stdarg.h> |
| 14 | 8 | #include <stdio.h> |
| 15 | 9 | #include <stdlib.h> |
| 16 | 10 | #include <string.h> |
| 17 | 11 | |
| 12 | #define lobject_c | |
| 13 | #define LUA_CORE | |
| 14 | ||
| 18 | 15 | #include "lua.h" |
| 19 | 16 | |
| 20 | 17 | #include "lctype.h" |
| r242899 | r242900 | |
| 73 | 70 | } |
| 74 | 71 | |
| 75 | 72 | |
| 76 | static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, | |
| 77 | lua_Integer v2) { | |
| 73 | lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { | |
| 78 | 74 | switch (op) { |
| 79 | case LUA_OPADD: return intop(+, v1, v2); | |
| 80 | case LUA_OPSUB:return intop(-, v1, v2); | |
| 81 | case LUA_OPMUL:return intop(*, v1, v2); | |
| 82 | case LUA_OPMOD: return luaV_mod(L, v1, v2); | |
| 83 | case LUA_OPIDIV: return luaV_div(L, v1, v2); | |
| 84 | case LUA_OPBAND: return intop(&, v1, v2); | |
| 85 | case LUA_OPBOR: return intop(|, v1, v2); | |
| 86 | case LUA_OPBXOR: return intop(^, v1, v2); | |
| 87 | case LUA_OPSHL: return luaV_shiftl(v1, v2); | |
| 88 | case LUA_OPSHR: return luaV_shiftl(v1, -v2); | |
| 89 | case LUA_OPUNM: return intop(-, 0, v1); | |
| 90 | case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1); | |
| 75 | case LUA_OPADD: return luai_numadd(NULL, v1, v2); | |
| 76 | case LUA_OPSUB: return luai_numsub(NULL, v1, v2); | |
| 77 | case LUA_OPMUL: return luai_nummul(NULL, v1, v2); | |
| 78 | case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); | |
| 79 | case LUA_OPMOD: return luai_nummod(NULL, v1, v2); | |
| 80 | case LUA_OPPOW: return luai_numpow(NULL, v1, v2); | |
| 81 | case LUA_OPUNM: return luai_numunm(NULL, v1); | |
| 91 | 82 | default: lua_assert(0); return 0; |
| 92 | 83 | } |
| 93 | 84 | } |
| 94 | 85 | |
| 95 | 86 | |
| 96 | static lua_Number numarith (lua_State *L, int op, lua_Number v1, | |
| 97 | lua_Number v2) { | |
| 98 | switch (op) { | |
| 99 | case LUA_OPADD: return luai_numadd(L, v1, v2); | |
| 100 | case LUA_OPSUB: return luai_numsub(L, v1, v2); | |
| 101 | case LUA_OPMUL: return luai_nummul(L, v1, v2); | |
| 102 | case LUA_OPDIV: return luai_numdiv(L, v1, v2); | |
| 103 | case LUA_OPPOW: return luai_numpow(L, v1, v2); | |
| 104 | case LUA_OPIDIV: return luai_numidiv(L, v1, v2); | |
| 105 | case LUA_OPUNM: return luai_numunm(L, v1); | |
| 106 | case LUA_OPMOD: { | |
| 107 | lua_Number m; | |
| 108 | luai_nummod(L, v1, v2, m); | |
| 109 | return m; | |
| 110 | } | |
| 111 | default: lua_assert(0); return 0; | |
| 112 | } | |
| 113 | } | |
| 114 | ||
| 115 | ||
| 116 | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | |
| 117 | TValue *res) { | |
| 118 | switch (op) { | |
| 119 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: | |
| 120 | case LUA_OPSHL: case LUA_OPSHR: | |
| 121 | case LUA_OPBNOT: { /* operate only on integers */ | |
| 122 | lua_Integer i1; lua_Integer i2; | |
| 123 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { | |
| 124 | setivalue(res, intarith(L, op, i1, i2)); | |
| 125 | return; | |
| 126 | } | |
| 127 | else break; /* go to the end */ | |
| 128 | } | |
| 129 | case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ | |
| 130 | lua_Number n1; lua_Number n2; | |
| 131 | if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | |
| 132 | setfltvalue(res, numarith(L, op, n1, n2)); | |
| 133 | return; | |
| 134 | } | |
| 135 | else break; /* go to the end */ | |
| 136 | } | |
| 137 | default: { /* other operations */ | |
| 138 | lua_Number n1; lua_Number n2; | |
| 139 | if (ttisinteger(p1) && ttisinteger(p2)) { | |
| 140 | setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); | |
| 141 | return; | |
| 142 | } | |
| 143 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | |
| 144 | setfltvalue(res, numarith(L, op, n1, n2)); | |
| 145 | return; | |
| 146 | } | |
| 147 | else break; /* go to the end */ | |
| 148 | } | |
| 149 | } | |
| 150 | /* could not perform raw operation; try metamethod */ | |
| 151 | lua_assert(L != NULL); /* should not fail when folding (compile time) */ | |
| 152 | luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD)); | |
| 153 | } | |
| 154 | ||
| 155 | ||
| 156 | 87 | int luaO_hexavalue (int c) { |
| 157 | 88 | if (lisdigit(c)) return c - '0'; |
| 158 | 89 | else return ltolower(c) - 'a' + 10; |
| 159 | 90 | } |
| 160 | 91 | |
| 161 | 92 | |
| 93 | #if !defined(lua_strx2number) | |
| 94 | ||
| 95 | #include <math.h> | |
| 96 | ||
| 97 | ||
| 162 | 98 | static int isneg (const char **s) { |
| 163 | 99 | if (**s == '-') { (*s)++; return 1; } |
| 164 | 100 | else if (**s == '+') (*s)++; |
| r242899 | r242900 | |
| 166 | 102 | } |
| 167 | 103 | |
| 168 | 104 | |
| 105 | static lua_Number readhexa (const char **s, lua_Number r, int *count) { | |
| 106 | for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */ | |
| 107 | r = (r * cast_num(16.0)) + cast_num(1.0*luaO_hexavalue(cast_uchar(**s))); | |
| 108 | (*count)++; | |
| 109 | } | |
| 110 | return r; | |
| 111 | } | |
| 169 | 112 | |
| 170 | /* | |
| 171 | ** {================================================================== | |
| 172 | ** Lua's implementation for 'lua_strx2number' | |
| 173 | ** =================================================================== | |
| 174 | */ | |
| 175 | #if !defined(lua_strx2number) | |
| 176 | 113 | |
| 177 | #include <math.h> | |
| 178 | ||
| 179 | /* maximum number of significant digits to read (to avoid overflows | |
| 180 | even with single floats) */ | |
| 181 | #define MAXSIGDIG 30 | |
| 182 | ||
| 183 | 114 | /* |
| 184 | 115 | ** convert an hexadecimal numeric string to a number, following |
| 185 | 116 | ** C99 specification for 'strtod' |
| 186 | 117 | */ |
| 187 | 118 | static lua_Number lua_strx2number (const char *s, char **endptr) { |
| 188 | lua_Number r = 0.0; /* result (accumulator) */ | |
| 189 | int sigdig = 0; /* number of significant digits */ | |
| 190 | int nosigdig = 0; /* number of non-significant digits */ | |
| 191 | int e = 0; /* exponent correction */ | |
| 192 | int neg; /* 1 if number is negative */ | |
| 193 | int dot = 0; /* true after seen a dot */ | |
| 119 | lua_Number r = 0.0; | |
| 120 | int e = 0, i = 0; | |
| 121 | int neg = 0; /* 1 if number is negative */ | |
| 194 | 122 | *endptr = cast(char *, s); /* nothing is valid yet */ |
| 195 | 123 | while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ |
| 196 | 124 | neg = isneg(&s); /* check signal */ |
| 197 | 125 | if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ |
| 198 | 126 | return 0.0; /* invalid format (no '0x') */ |
| 199 | for (s += 2; ; s++) { /* skip '0x' and read numeral */ | |
| 200 | if (*s == '.') { | |
| 201 | if (dot) break; /* second dot? stop loop */ | |
| 202 | else dot = 1; | |
| 203 | } | |
| 204 | else if (lisxdigit(cast_uchar(*s))) { | |
| 205 | if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */ | |
| 206 | nosigdig++; | |
| 207 | else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ | |
| 208 | r = (r * cast_num(16.0)) + luaO_hexavalue(*s); | |
| 209 | else e++; /* too many digits; ignore, but still count for exponent */ | |
| 210 | if (dot) e--; /* decimal digit? correct exponent */ | |
| 211 | } | |
| 212 | else break; /* neither a dot nor a digit */ | |
| 127 | s += 2; /* skip '0x' */ | |
| 128 | r = readhexa(&s, r, &i); /* read integer part */ | |
| 129 | if (*s == '.') { | |
| 130 | s++; /* skip dot */ | |
| 131 | r = readhexa(&s, r, &e); /* read fractional part */ | |
| 213 | 132 | } |
| 214 | if (nosigdig + sigdig == 0) /* no digits? */ | |
| 215 | return 0.0; /* invalid format */ | |
| 133 | if (i == 0 && e == 0) | |
| 134 | return 0.0; /* invalid format (no digit) */ | |
| 135 | e *= -4; /* each fractional digit divides value by 2^-4 */ | |
| 216 | 136 | *endptr = cast(char *, s); /* valid up to here */ |
| 217 | e *= 4; /* each digit multiplies/divides value by 2^4 */ | |
| 218 | 137 | if (*s == 'p' || *s == 'P') { /* exponent part? */ |
| 219 | int exp1 = 0; /* exponent value */ | |
| 220 | int neg1; /* exponent signal */ | |
| 138 | int exp1 = 0; | |
| 139 | int neg1; | |
| 221 | 140 | s++; /* skip 'p' */ |
| 222 | 141 | neg1 = isneg(&s); /* signal */ |
| 223 | 142 | if (!lisdigit(cast_uchar(*s))) |
| 224 | ret | |
| 143 | goto ret; /* must have at least one digit */ | |
| 225 | 144 | while (lisdigit(cast_uchar(*s))) /* read exponent */ |
| 226 | 145 | exp1 = exp1 * 10 + *(s++) - '0'; |
| 227 | 146 | if (neg1) exp1 = -exp1; |
| 228 | 147 | e += exp1; |
| 229 | *endptr = cast(char *, s); /* valid up to here */ | |
| 230 | 148 | } |
| 149 | *endptr = cast(char *, s); /* valid up to here */ | |
| 150 | ret: | |
| 231 | 151 | if (neg) r = -r; |
| 232 | 152 | return l_mathop(ldexp)(r, e); |
| 233 | 153 | } |
| 234 | 154 | |
| 235 | 155 | #endif |
| 236 | /* }====================================================== */ | |
| 237 | 156 | |
| 238 | 157 | |
| 239 | ||
| 158 | int luaO_str2d (const char *s, size_t len, lua_Number *result) { | |
| 240 | 159 | char *endptr; |
| 241 | 160 | if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */ |
| 242 | return NULL; | |
| 243 | else if (strpbrk(s, "xX")) /* hex? */ | |
| 161 | return 0; | |
| 162 | else if (strpbrk(s, "xX")) /* hexa? */ | |
| 244 | 163 | *result = lua_strx2number(s, &endptr); |
| 245 | 164 | else |
| 246 | 165 | *result = lua_str2number(s, &endptr); |
| 247 | 166 | if (endptr == s) return 0; /* nothing recognized */ |
| 248 | 167 | while (lisspace(cast_uchar(*endptr))) endptr++; |
| 249 | return ( | |
| 168 | return (endptr == s + len); /* OK if no trailing characters */ | |
| 250 | 169 | } |
| 251 | 170 | |
| 252 | 171 | |
| 253 | static const char *l_str2int (const char *s, lua_Integer *result) { | |
| 254 | lua_Unsigned a = 0; | |
| 255 | int empty = 1; | |
| 256 | int neg; | |
| 257 | while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ | |
| 258 | neg = isneg(&s); | |
| 259 | if (s[0] == '0' && | |
| 260 | (s[1] == 'x' || s[1] == 'X')) { /* hex? */ | |
| 261 | s += 2; /* skip '0x' */ | |
| 262 | for (; lisxdigit(cast_uchar(*s)); s++) { | |
| 263 | a = a * 16 + luaO_hexavalue(*s); | |
| 264 | empty = 0; | |
| 265 | } | |
| 266 | } | |
| 267 | else { /* decimal */ | |
| 268 | for (; lisdigit(cast_uchar(*s)); s++) { | |
| 269 | a = a * 10 + *s - '0'; | |
| 270 | empty = 0; | |
| 271 | } | |
| 272 | } | |
| 273 | while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */ | |
| 274 | if (empty || *s != '\0') return NULL; /* something wrong in the numeral */ | |
| 275 | else { | |
| 276 | *result = l_castU2S((neg) ? 0u - a : a); | |
| 277 | return s; | |
| 278 | } | |
| 279 | } | |
| 280 | 172 | |
| 281 | ||
| 282 | size_t luaO_str2num (const char *s, TValue *o) { | |
| 283 | lua_Integer i; lua_Number n; | |
| 284 | const char *e; | |
| 285 | if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */ | |
| 286 | setivalue(o, i); | |
| 287 | } | |
| 288 | else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */ | |
| 289 | setfltvalue(o, n); | |
| 290 | } | |
| 291 | else | |
| 292 | return 0; /* conversion failed */ | |
| 293 | return (e - s + 1); /* success; return string size */ | |
| 294 | } | |
| 295 | ||
| 296 | ||
| 297 | int luaO_utf8esc (char *buff, unsigned long x) { | |
| 298 | int n = 1; /* number of bytes put in buffer (backwards) */ | |
| 299 | lua_assert(x <= 0x10FFFF); | |
| 300 | if (x < 0x80) /* ascii? */ | |
| 301 | buff[UTF8BUFFSZ - 1] = cast(char, x); | |
| 302 | else { /* need continuation bytes */ | |
| 303 | unsigned int mfb = 0x3f; /* maximum that fits in first byte */ | |
| 304 | do { /* add continuation bytes */ | |
| 305 | buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f)); | |
| 306 | x >>= 6; /* remove added bits */ | |
| 307 | mfb >>= 1; /* now there is one less bit available in first byte */ | |
| 308 | } while (x > mfb); /* still needs continuation byte? */ | |
| 309 | buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */ | |
| 310 | } | |
| 311 | return n; | |
| 312 | } | |
| 313 | ||
| 314 | ||
| 315 | /* maximum length of the conversion of a number to a string */ | |
| 316 | #define MAXNUMBER2STR 50 | |
| 317 | ||
| 318 | ||
| 319 | /* | |
| 320 | ** Convert a number object to a string | |
| 321 | */ | |
| 322 | void luaO_tostring (lua_State *L, StkId obj) { | |
| 323 | char buff[MAXNUMBER2STR]; | |
| 324 | size_t len; | |
| 325 | lua_assert(ttisnumber(obj)); | |
| 326 | if (ttisinteger(obj)) | |
| 327 | len = lua_integer2str(buff, ivalue(obj)); | |
| 328 | else { | |
| 329 | len = lua_number2str(buff, fltvalue(obj)); | |
| 330 | #if !defined(LUA_COMPAT_FLOATSTRING) | |
| 331 | if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ | |
| 332 | buff[len++] = '.'; | |
| 333 | buff[len++] = '0'; /* adds '.0' to result */ | |
| 334 | } | |
| 335 | #endif | |
| 336 | } | |
| 337 | setsvalue2s(L, obj, luaS_newlstr(L, buff, len)); | |
| 338 | } | |
| 339 | ||
| 340 | ||
| 341 | 173 | static void pushstr (lua_State *L, const char *str, size_t l) { |
| 342 | 174 | setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); |
| 343 | 175 | } |
| 344 | 176 | |
| 345 | 177 | |
| 346 | /* this function handles only '%d', '%c', '%f', '%p', and '%s' | |
| 347 | conventional formats, plus Lua-specific '%I' and '%U' */ | |
| 178 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ | |
| 348 | 179 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
| 349 | 180 | int n = 0; |
| 350 | 181 | for (;;) { |
| r242899 | r242900 | |
| 360 | 191 | break; |
| 361 | 192 | } |
| 362 | 193 | case 'c': { |
| 363 | char buff = cast(char, va_arg(argp, int)); | |
| 364 | if (lisprint(cast_uchar(buff))) | |
| 365 | pushstr(L, &buff, 1); | |
| 366 | else /* non-printable character; print its code */ | |
| 367 | luaO_pushfstring(L, "<\\%d>", cast_uchar(buff)); | |
| 194 | char buff; | |
| 195 | buff = cast(char, va_arg(argp, int)); | |
| 196 | pushstr(L, &buff, 1); | |
| 368 | 197 | break; |
| 369 | 198 | } |
| 370 | 199 | case 'd': { |
| 371 | setivalue(L->top++, va_arg(argp, int)); | |
| 372 | luaO_tostring(L, L->top - 1); | |
| 200 | setnvalue(L->top++, cast_num(va_arg(argp, int))); | |
| 373 | 201 | break; |
| 374 | 202 | } |
| 375 | case 'I': { | |
| 376 | setivalue(L->top++, cast(lua_Integer, va_arg(argp, l_uacInt))); | |
| 377 | luaO_tostring(L, L->top - 1); | |
| 378 | break; | |
| 379 | } | |
| 380 | 203 | case 'f': { |
| 381 | setfltvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); | |
| 382 | luaO_tostring(L, L->top - 1); | |
| 204 | setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); | |
| 383 | 205 | break; |
| 384 | 206 | } |
| 385 | 207 | case 'p': { |
| 386 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a | |
| 208 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ | |
| 387 | 209 | int l = sprintf(buff, "%p", va_arg(argp, void *)); |
| 388 | 210 | pushstr(L, buff, l); |
| 389 | 211 | break; |
| 390 | 212 | } |
| 391 | case 'U': { | |
| 392 | char buff[UTF8BUFFSZ]; | |
| 393 | int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long))); | |
| 394 | pushstr(L, buff + UTF8BUFFSZ - l, l); | |
| 395 | break; | |
| 396 | } | |
| 397 | 213 | case '%': { |
| 398 | 214 | pushstr(L, "%", 1); |
| 399 | 215 | break; |
| 400 | 216 | } |
| 401 | 217 | default: { |
| 402 | luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'", | |
| 403 | *(e + 1)); | |
| 218 | luaG_runerror(L, | |
| 219 | "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"), | |
| 220 | *(e + 1)); | |
| 404 | 221 | } |
| 405 | 222 | } |
| 406 | 223 | n += 2; |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.1 | |
| 2 | ** $Id: lobject.h,v 2.71.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Type definitions for Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 20 | 20 | ** Extra tags for non-values |
| 21 | 21 | */ |
| 22 | 22 | #define LUA_TPROTO LUA_NUMTAGS |
| 23 | #define LUA_TDEADKEY (LUA_NUMTAGS+1) | |
| 23 | #define LUA_TUPVAL (LUA_NUMTAGS+1) | |
| 24 | #define LUA_TDEADKEY (LUA_NUMTAGS+2) | |
| 24 | 25 | |
| 25 | 26 | /* |
| 26 | 27 | ** number of all possible tags (including LUA_TNONE but excluding DEADKEY) |
| 27 | 28 | */ |
| 28 | #define LUA_TOTALTAGS (LUA_TP | |
| 29 | #define LUA_TOTALTAGS (LUA_TUPVAL+2) | |
| 29 | 30 | |
| 30 | 31 | |
| 31 | 32 | /* |
| r242899 | r242900 | |
| 56 | 57 | #define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */ |
| 57 | 58 | |
| 58 | 59 | |
| 59 | /* Variant tags for numbers */ | |
| 60 | #define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */ | |
| 61 | #define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */ | |
| 62 | ||
| 63 | ||
| 64 | 60 | /* Bit mark for collectable types */ |
| 65 | 61 | #define BIT_ISCOLLECTABLE (1 << 6) |
| 66 | 62 | |
| r242899 | r242900 | |
| 69 | 65 | |
| 70 | 66 | |
| 71 | 67 | /* |
| 72 | ** | |
| 68 | ** Union of all collectable objects | |
| 73 | 69 | */ |
| 74 | typedef | |
| 70 | typedef union GCObject GCObject; | |
| 75 | 71 | |
| 76 | 72 | |
| 77 | 73 | /* |
| r242899 | r242900 | |
| 82 | 78 | |
| 83 | 79 | |
| 84 | 80 | /* |
| 85 | ** Common | |
| 81 | ** Common header in struct form | |
| 86 | 82 | */ |
| 87 | struct GC | |
| 83 | typedef struct GCheader { | |
| 88 | 84 | CommonHeader; |
| 89 | }; | |
| 85 | } GCheader; | |
| 90 | 86 | |
| 91 | 87 | |
| 92 | 88 | |
| r242899 | r242900 | |
| 96 | 92 | typedef union Value Value; |
| 97 | 93 | |
| 98 | 94 | |
| 95 | #define numfield lua_Number n; /* numbers */ | |
| 99 | 96 | |
| 100 | 97 | |
| 98 | ||
| 101 | 99 | /* |
| 102 | 100 | ** Tagged Values. This is the basic representation of values in Lua, |
| 103 | 101 | ** an actual value plus a tag with its type. |
| r242899 | r242900 | |
| 113 | 111 | |
| 114 | 112 | |
| 115 | 113 | #define val_(o) ((o)->value_) |
| 114 | #define num_(o) (val_(o).n) | |
| 116 | 115 | |
| 117 | 116 | |
| 118 | 117 | /* raw type tag of a TValue */ |
| r242899 | r242900 | |
| 125 | 124 | #define ttype(o) (rttype(o) & 0x3F) |
| 126 | 125 | |
| 127 | 126 | /* type tag of a TValue with no variants (bits 0-3) */ |
| 128 | #define ttn | |
| 127 | #define ttypenv(o) (novariant(rttype(o))) | |
| 129 | 128 | |
| 130 | 129 | |
| 131 | 130 | /* Macros to test type */ |
| 132 | 131 | #define checktag(o,t) (rttype(o) == (t)) |
| 133 | #define checktype(o,t) (ttnov(o) == (t)) | |
| 134 | #define ttisnumber(o) checktype((o), LUA_TNUMBER) | |
| 135 | #define ttisfloat(o) checktag((o), LUA_TNUMFLT) | |
| 136 | #define ttisinteger(o) checktag((o), LUA_TNUMINT) | |
| 132 | #define checktype(o,t) (ttypenv(o) == (t)) | |
| 133 | #define ttisnumber(o) checktag((o), LUA_TNUMBER) | |
| 137 | 134 | #define ttisnil(o) checktag((o), LUA_TNIL) |
| 138 | 135 | #define ttisboolean(o) checktag((o), LUA_TBOOLEAN) |
| 139 | 136 | #define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) |
| r242899 | r242900 | |
| 146 | 143 | #define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) |
| 147 | 144 | #define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) |
| 148 | 145 | #define ttislcf(o) checktag((o), LUA_TLCF) |
| 149 | #define ttis | |
| 146 | #define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) | |
| 150 | 147 | #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) |
| 151 | 148 | #define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) |
| 152 | 149 | |
| 150 | #define ttisequal(o1,o2) (rttype(o1) == rttype(o2)) | |
| 153 | 151 | |
| 154 | 152 | /* Macros to access values */ |
| 155 | #define ivalue(o) check_exp(ttisinteger(o), val_(o).i) | |
| 156 | #define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) | |
| 157 | #define nvalue(o) check_exp(ttisnumber(o), \ | |
| 158 | (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) | |
| 153 | #define nvalue(o) check_exp(ttisnumber(o), num_(o)) | |
| 159 | 154 | #define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) |
| 160 | 155 | #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) |
| 161 | #define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) | |
| 162 | #define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) | |
| 163 | #define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) | |
| 164 | #define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) | |
| 165 | #define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) | |
| 156 | #define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) | |
| 157 | #define tsvalue(o) (&rawtsvalue(o)->tsv) | |
| 158 | #define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) | |
| 159 | #define uvalue(o) (&rawuvalue(o)->uv) | |
| 160 | #define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) | |
| 161 | #define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) | |
| 162 | #define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c) | |
| 166 | 163 | #define fvalue(o) check_exp(ttislcf(o), val_(o).f) |
| 167 | #define hvalue(o) check_exp(ttistable(o), | |
| 164 | #define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) | |
| 168 | 165 | #define bvalue(o) check_exp(ttisboolean(o), val_(o).b) |
| 169 | #define thvalue(o) check_exp(ttisthread(o), | |
| 166 | #define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th) | |
| 170 | 167 | /* a dead value may get the 'gc' field, but cannot access its contents */ |
| 171 | 168 | #define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) |
| 172 | 169 | |
| r242899 | r242900 | |
| 177 | 174 | |
| 178 | 175 | |
| 179 | 176 | /* Macros for internal tests */ |
| 180 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->tt) | |
| 177 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) | |
| 181 | 178 | |
| 182 | 179 | #define checkliveness(g,obj) \ |
| 183 | 180 | lua_longassert(!iscollectable(obj) || \ |
| r242899 | r242900 | |
| 187 | 184 | /* Macros to set values */ |
| 188 | 185 | #define settt_(o,t) ((o)->tt_=(t)) |
| 189 | 186 | |
| 190 | #define setfltvalue(obj,x) \ | |
| 191 | { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); } | |
| 187 | #define setnvalue(obj,x) \ | |
| 188 | { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } | |
| 192 | 189 | |
| 193 | #define setivalue(obj,x) \ | |
| 194 | { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); } | |
| 195 | ||
| 196 | 190 | #define setnilvalue(obj) settt_(obj, LUA_TNIL) |
| 197 | 191 | |
| 198 | 192 | #define setfvalue(obj,x) \ |
| r242899 | r242900 | |
| 205 | 199 | { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } |
| 206 | 200 | |
| 207 | 201 | #define setgcovalue(L,obj,x) \ |
| 208 | { TValue *io = (obj); GCObject *i_g=(x); \ | |
| 209 | val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); } | |
| 202 | { TValue *io=(obj); GCObject *i_g=(x); \ | |
| 203 | val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); } | |
| 210 | 204 | |
| 211 | 205 | #define setsvalue(L,obj,x) \ |
| 212 | { TValue *io = (obj); TString *x_ = (x); \ | |
| 213 | val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ | |
| 206 | { TValue *io=(obj); \ | |
| 207 | TString *x_ = (x); \ | |
| 208 | val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \ | |
| 214 | 209 | checkliveness(G(L),io); } |
| 215 | 210 | |
| 216 | 211 | #define setuvalue(L,obj,x) \ |
| 217 | { TValue *io = (obj); Udata *x_ = (x); \ | |
| 218 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \ | |
| 212 | { TValue *io=(obj); \ | |
| 213 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \ | |
| 219 | 214 | checkliveness(G(L),io); } |
| 220 | 215 | |
| 221 | 216 | #define setthvalue(L,obj,x) \ |
| 222 | { TValue *io = (obj); lua_State *x_ = (x); \ | |
| 223 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \ | |
| 217 | { TValue *io=(obj); \ | |
| 218 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ | |
| 224 | 219 | checkliveness(G(L),io); } |
| 225 | 220 | |
| 226 | 221 | #define setclLvalue(L,obj,x) \ |
| 227 | { TValue *io = (obj); LClosure *x_ = (x); \ | |
| 228 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \ | |
| 222 | { TValue *io=(obj); \ | |
| 223 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \ | |
| 229 | 224 | checkliveness(G(L),io); } |
| 230 | 225 | |
| 231 | 226 | #define setclCvalue(L,obj,x) \ |
| 232 | { TValue *io = (obj); CClosure *x_ = (x); \ | |
| 233 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \ | |
| 227 | { TValue *io=(obj); \ | |
| 228 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \ | |
| 234 | 229 | checkliveness(G(L),io); } |
| 235 | 230 | |
| 236 | 231 | #define sethvalue(L,obj,x) \ |
| 237 | { TValue *io = (obj); Table *x_ = (x); \ | |
| 238 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \ | |
| 232 | { TValue *io=(obj); \ | |
| 233 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \ | |
| 239 | 234 | checkliveness(G(L),io); } |
| 240 | 235 | |
| 241 | 236 | #define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) |
| r242899 | r242900 | |
| 243 | 238 | |
| 244 | 239 | |
| 245 | 240 | #define setobj(L,obj1,obj2) \ |
| 246 | { TValue *io1=(obj1); *io1 = *(obj2); \ | |
| 247 | (void)L; checkliveness(G(L),io1); } | |
| 241 | { const TValue *io2=(obj2); TValue *io1=(obj1); \ | |
| 242 | io1->value_ = io2->value_; io1->tt_ = io2->tt_; \ | |
| 243 | checkliveness(G(L),io1); } | |
| 248 | 244 | |
| 249 | 245 | |
| 250 | 246 | /* |
| r242899 | r242900 | |
| 267 | 263 | #define setsvalue2n setsvalue |
| 268 | 264 | |
| 269 | 265 | |
| 266 | /* check whether a number is valid (useful only for NaN trick) */ | |
| 267 | #define luai_checknum(L,o,c) { /* empty */ } | |
| 270 | 268 | |
| 271 | 269 | |
| 272 | 270 | /* |
| 273 | 271 | ** {====================================================== |
| 272 | ** NaN Trick | |
| 273 | ** ======================================================= | |
| 274 | */ | |
| 275 | #if defined(LUA_NANTRICK) | |
| 276 | ||
| 277 | /* | |
| 278 | ** numbers are represented in the 'd_' field. All other values have the | |
| 279 | ** value (NNMARK | tag) in 'tt__'. A number with such pattern would be | |
| 280 | ** a "signaled NaN", which is never generated by regular operations by | |
| 281 | ** the CPU (nor by 'strtod') | |
| 282 | */ | |
| 283 | ||
| 284 | /* allows for external implementation for part of the trick */ | |
| 285 | #if !defined(NNMARK) /* { */ | |
| 286 | ||
| 287 | ||
| 288 | #if !defined(LUA_IEEEENDIAN) | |
| 289 | #error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN' | |
| 290 | #endif | |
| 291 | ||
| 292 | ||
| 293 | #define NNMARK 0x7FF7A500 | |
| 294 | #define NNMASK 0x7FFFFF00 | |
| 295 | ||
| 296 | #undef TValuefields | |
| 297 | #undef NILCONSTANT | |
| 298 | ||
| 299 | #if (LUA_IEEEENDIAN == 0) /* { */ | |
| 300 | ||
| 301 | /* little endian */ | |
| 302 | #define TValuefields \ | |
| 303 | union { struct { Value v__; int tt__; } i; double d__; } u | |
| 304 | #define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}} | |
| 305 | /* field-access macros */ | |
| 306 | #define v_(o) ((o)->u.i.v__) | |
| 307 | #define d_(o) ((o)->u.d__) | |
| 308 | #define tt_(o) ((o)->u.i.tt__) | |
| 309 | ||
| 310 | #else /* }{ */ | |
| 311 | ||
| 312 | /* big endian */ | |
| 313 | #define TValuefields \ | |
| 314 | union { struct { int tt__; Value v__; } i; double d__; } u | |
| 315 | #define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}} | |
| 316 | /* field-access macros */ | |
| 317 | #define v_(o) ((o)->u.i.v__) | |
| 318 | #define d_(o) ((o)->u.d__) | |
| 319 | #define tt_(o) ((o)->u.i.tt__) | |
| 320 | ||
| 321 | #endif /* } */ | |
| 322 | ||
| 323 | #endif /* } */ | |
| 324 | ||
| 325 | ||
| 326 | /* correspondence with standard representation */ | |
| 327 | #undef val_ | |
| 328 | #define val_(o) v_(o) | |
| 329 | #undef num_ | |
| 330 | #define num_(o) d_(o) | |
| 331 | ||
| 332 | ||
| 333 | #undef numfield | |
| 334 | #define numfield /* no such field; numbers are the entire struct */ | |
| 335 | ||
| 336 | /* basic check to distinguish numbers from non-numbers */ | |
| 337 | #undef ttisnumber | |
| 338 | #define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK) | |
| 339 | ||
| 340 | #define tag2tt(t) (NNMARK | (t)) | |
| 341 | ||
| 342 | #undef rttype | |
| 343 | #define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff) | |
| 344 | ||
| 345 | #undef settt_ | |
| 346 | #define settt_(o,t) (tt_(o) = tag2tt(t)) | |
| 347 | ||
| 348 | #undef setnvalue | |
| 349 | #define setnvalue(obj,x) \ | |
| 350 | { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); } | |
| 351 | ||
| 352 | #undef setobj | |
| 353 | #define setobj(L,obj1,obj2) \ | |
| 354 | { const TValue *o2_=(obj2); TValue *o1_=(obj1); \ | |
| 355 | o1_->u = o2_->u; \ | |
| 356 | checkliveness(G(L),o1_); } | |
| 357 | ||
| 358 | ||
| 359 | /* | |
| 360 | ** these redefinitions are not mandatory, but these forms are more efficient | |
| 361 | */ | |
| 362 | ||
| 363 | #undef checktag | |
| 364 | #undef checktype | |
| 365 | #define checktag(o,t) (tt_(o) == tag2tt(t)) | |
| 366 | #define checktype(o,t) (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS)) | |
| 367 | ||
| 368 | #undef ttisequal | |
| 369 | #define ttisequal(o1,o2) \ | |
| 370 | (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2))) | |
| 371 | ||
| 372 | ||
| 373 | #undef luai_checknum | |
| 374 | #define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } | |
| 375 | ||
| 376 | #endif | |
| 377 | /* }====================================================== */ | |
| 378 | ||
| 379 | ||
| 380 | ||
| 381 | /* | |
| 382 | ** {====================================================== | |
| 274 | 383 | ** types and prototypes |
| 275 | 384 | ** ======================================================= |
| 276 | 385 | */ |
| r242899 | r242900 | |
| 281 | 390 | void *p; /* light userdata */ |
| 282 | 391 | int b; /* booleans */ |
| 283 | 392 | lua_CFunction f; /* light C functions */ |
| 284 | lua_Integer i; /* integer numbers */ | |
| 285 | lua_Number n; /* float numbers */ | |
| 393 | numfield /* numbers */ | |
| 286 | 394 | }; |
| 287 | 395 | |
| 288 | 396 | |
| r242899 | r242900 | |
| 298 | 406 | |
| 299 | 407 | /* |
| 300 | 408 | ** Header for string value; string bytes follow the end of this structure |
| 301 | ** (aligned according to 'UTString'; see next). | |
| 302 | 409 | */ |
| 303 | typedef struct TString { | |
| 304 | CommonHeader; | |
| 305 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ | |
| 306 | unsigned int hash; | |
| 307 | size_t len; /* number of characters in string */ | |
| 308 | struct TString *hnext; /* linked list for hash table */ | |
| 410 | typedef union TString { | |
| 411 | L_Umaxalign dummy; /* ensures maximum alignment for strings */ | |
| 412 | struct { | |
| 413 | CommonHeader; | |
| 414 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ | |
| 415 | unsigned int hash; | |
| 416 | size_t len; /* number of characters in string */ | |
| 417 | } tsv; | |
| 309 | 418 | } TString; |
| 310 | 419 | |
| 311 | 420 | |
| 312 | /* | |
| 313 | ** Ensures that address after this type is always fully aligned. | |
| 314 | */ | |
| 315 | typedef union UTString { | |
| 316 | L_Umaxalign dummy; /* ensures maximum alignment for strings */ | |
| 317 | TString tsv; | |
| 318 | } UTString; | |
| 421 | /* get the actual string (array of bytes) from a TString */ | |
| 422 | #define getstr(ts) cast(const char *, (ts) + 1) | |
| 319 | 423 | |
| 320 | ||
| 321 | /* | |
| 322 | ** Get the actual string (array of bytes) from a 'TString'. | |
| 323 | ** (Access to 'extra' ensures that value is really a 'TString'.) | |
| 324 | */ | |
| 325 | #define getaddrstr(ts) (cast(char *, (ts)) + sizeof(UTString)) | |
| 326 | #define getstr(ts) \ | |
| 327 | check_exp(sizeof((ts)->extra), cast(const char*, getaddrstr(ts))) | |
| 328 | ||
| 329 | 424 | /* get the actual string (array of bytes) from a Lua value */ |
| 330 | #define svalue(o) getstr(tsvalue(o)) | |
| 425 | #define svalue(o) getstr(rawtsvalue(o)) | |
| 331 | 426 | |
| 332 | 427 | |
| 333 | 428 | /* |
| 334 | 429 | ** Header for userdata; memory area follows the end of this structure |
| 335 | ** (aligned according to 'UUdata'; see next). | |
| 336 | 430 | */ |
| 337 | typedef struct Udata { | |
| 338 | CommonHeader; | |
| 339 | lu_byte ttuv_; /* user value's tag */ | |
| 340 | struct Table *metatable; | |
| 341 | size_t len; /* number of bytes */ | |
| 342 | union Value user_; /* user value */ | |
| 431 | typedef union Udata { | |
| 432 | L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ | |
| 433 | struct { | |
| 434 | CommonHeader; | |
| 435 | struct Table *metatable; | |
| 436 | struct Table *env; | |
| 437 | size_t len; /* number of bytes */ | |
| 438 | } uv; | |
| 343 | 439 | } Udata; |
| 344 | 440 | |
| 345 | 441 | |
| 346 | /* | |
| 347 | ** Ensures that address after this type is always fully aligned. | |
| 348 | */ | |
| 349 | typedef union UUdata { | |
| 350 | L_Umaxalign dummy; /* ensures maximum alignment for 'local' udata */ | |
| 351 | Udata uv; | |
| 352 | } UUdata; | |
| 353 | 442 | |
| 354 | ||
| 355 | 443 | /* |
| 356 | ** Get the address of memory block inside 'Udata'. | |
| 357 | ** (Access to 'ttuv_' ensures that value is really a 'Udata'.) | |
| 358 | */ | |
| 359 | #define getudatamem(u) \ | |
| 360 | check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata))) | |
| 361 | ||
| 362 | #define setuservalue(L,u,o) \ | |
| 363 | { const TValue *io=(o); Udata *iu = (u); \ | |
| 364 | iu->user_ = io->value_; iu->ttuv_ = io->tt_; \ | |
| 365 | checkliveness(G(L),io); } | |
| 366 | ||
| 367 | ||
| 368 | #define getuservalue(L,u,o) \ | |
| 369 | { TValue *io=(o); const Udata *iu = (u); \ | |
| 370 | io->value_ = iu->user_; io->tt_ = iu->ttuv_; \ | |
| 371 | checkliveness(G(L),io); } | |
| 372 | ||
| 373 | ||
| 374 | /* | |
| 375 | 444 | ** Description of an upvalue for function prototypes |
| 376 | 445 | */ |
| 377 | 446 | typedef struct Upvaldesc { |
| r242899 | r242900 | |
| 397 | 466 | */ |
| 398 | 467 | typedef struct Proto { |
| 399 | 468 | CommonHeader; |
| 400 | lu_byte numparams; /* number of fixed parameters */ | |
| 401 | lu_byte is_vararg; | |
| 402 | lu_byte maxstacksize; /* maximum stack used by this function */ | |
| 403 | int sizeupvalues; /* size of 'upvalues' */ | |
| 404 | int sizek; /* size of 'k' */ | |
| 405 | int sizecode; | |
| 406 | int sizelineinfo; | |
| 407 | int sizep; /* size of 'p' */ | |
| 408 | int sizelocvars; | |
| 409 | int linedefined; | |
| 410 | int lastlinedefined; | |
| 411 | 469 | TValue *k; /* constants used by the function */ |
| 412 | 470 | Instruction *code; |
| 413 | 471 | struct Proto **p; /* functions defined inside the function */ |
| 414 | 472 | int *lineinfo; /* map from opcodes to source lines (debug information) */ |
| 415 | 473 | LocVar *locvars; /* information about local variables (debug information) */ |
| 416 | 474 | Upvaldesc *upvalues; /* upvalue information */ |
| 417 | | |
| 475 | union Closure *cache; /* last created closure with this prototype */ | |
| 418 | 476 | TString *source; /* used for debug information */ |
| 477 | int sizeupvalues; /* size of 'upvalues' */ | |
| 478 | int sizek; /* size of `k' */ | |
| 479 | int sizecode; | |
| 480 | int sizelineinfo; | |
| 481 | int sizep; /* size of `p' */ | |
| 482 | int sizelocvars; | |
| 483 | int linedefined; | |
| 484 | int lastlinedefined; | |
| 419 | 485 | GCObject *gclist; |
| 486 | lu_byte numparams; /* number of fixed parameters */ | |
| 487 | lu_byte is_vararg; | |
| 488 | lu_byte maxstacksize; /* maximum stack used by this function */ | |
| 420 | 489 | } Proto; |
| 421 | 490 | |
| 422 | 491 | |
| r242899 | r242900 | |
| 424 | 493 | /* |
| 425 | 494 | ** Lua Upvalues |
| 426 | 495 | */ |
| 427 | typedef struct UpVal UpVal; | |
| 496 | typedef struct UpVal { | |
| 497 | CommonHeader; | |
| 498 | TValue *v; /* points to stack or to its own value */ | |
| 499 | union { | |
| 500 | TValue value; /* the value (when closed) */ | |
| 501 | struct { /* double linked list (when open) */ | |
| 502 | struct UpVal *prev; | |
| 503 | struct UpVal *next; | |
| 504 | } l; | |
| 505 | } u; | |
| 506 | } UpVal; | |
| 428 | 507 | |
| 429 | 508 | |
| 430 | 509 | /* |
| r242899 | r242900 | |
| 466 | 545 | typedef union TKey { |
| 467 | 546 | struct { |
| 468 | 547 | TValuefields; |
| 469 | | |
| 548 | struct Node *next; /* for chaining */ | |
| 470 | 549 | } nk; |
| 471 | 550 | TValue tvk; |
| 472 | 551 | } TKey; |
| 473 | 552 | |
| 474 | 553 | |
| 475 | /* copy a value into a key without messing up field 'next' */ | |
| 476 | #define setnodekey(L,key,obj) \ | |
| 477 | { TKey *k_=(key); const TValue *io_=(obj); \ | |
| 478 | k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \ | |
| 479 | (void)L; checkliveness(G(L),io_); } | |
| 480 | ||
| 481 | ||
| 482 | 554 | typedef struct Node { |
| 483 | 555 | TValue i_val; |
| 484 | 556 | TKey i_key; |
| r242899 | r242900 | |
| 488 | 560 | typedef struct Table { |
| 489 | 561 | CommonHeader; |
| 490 | 562 | lu_byte flags; /* 1<<p means tagmethod(p) is not present */ |
| 491 | lu_byte lsizenode; /* log2 of size of 'node' array */ | |
| 492 | unsigned int sizearray; /* size of 'array' array */ | |
| 563 | lu_byte lsizenode; /* log2 of size of `node' array */ | |
| 564 | struct Table *metatable; | |
| 493 | 565 | TValue *array; /* array part */ |
| 494 | 566 | Node *node; |
| 495 | 567 | Node *lastfree; /* any free position is before this position */ |
| 496 | struct Table *metatable; | |
| 497 | 568 | GCObject *gclist; |
| 569 | int sizearray; /* size of `array' array */ | |
| 498 | 570 | } Table; |
| 499 | 571 | |
| 500 | 572 | |
| 501 | 573 | |
| 502 | 574 | /* |
| 503 | ** | |
| 575 | ** `module' operation for hashing (size is always a power of 2) | |
| 504 | 576 | */ |
| 505 | 577 | #define lmod(s,size) \ |
| 506 | 578 | (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1))))) |
| r242899 | r242900 | |
| 518 | 590 | |
| 519 | 591 | LUAI_DDEC const TValue luaO_nilobject_; |
| 520 | 592 | |
| 521 | /* size of buffer for 'luaO_utf8esc' function */ | |
| 522 | #define UTF8BUFFSZ 8 | |
| 523 | 593 | |
| 524 | 594 | LUAI_FUNC int luaO_int2fb (unsigned int x); |
| 525 | 595 | LUAI_FUNC int luaO_fb2int (int x); |
| 526 | LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); | |
| 527 | 596 | LUAI_FUNC int luaO_ceillog2 (unsigned int x); |
| 528 | LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, | |
| 529 | const TValue *p2, TValue *res); | |
| 530 | LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); | |
| 597 | LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2); | |
| 598 | LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result); | |
| 531 | 599 | LUAI_FUNC int luaO_hexavalue (int c); |
| 532 | LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj); | |
| 533 | 600 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, |
| 534 | 601 | va_list argp); |
| 535 | 602 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lopcodes.c,v 1. | |
| 2 | ** $Id: lopcodes.c,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Opcodes for Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | ||
| 7 | 8 | #define lopcodes_c |
| 8 | 9 | #define LUA_CORE |
| 9 | 10 | |
| 10 | #include "lprefix.h" | |
| 11 | 11 | |
| 12 | ||
| 13 | #include <stddef.h> | |
| 14 | ||
| 15 | 12 | #include "lopcodes.h" |
| 16 | 13 | |
| 17 | 14 | |
| r242899 | r242900 | |
| 34 | 31 | "ADD", |
| 35 | 32 | "SUB", |
| 36 | 33 | "MUL", |
| 34 | "DIV", | |
| 37 | 35 | "MOD", |
| 38 | 36 | "POW", |
| 39 | "DIV", | |
| 40 | "IDIV", | |
| 41 | "BAND", | |
| 42 | "BOR", | |
| 43 | "BXOR", | |
| 44 | "SHL", | |
| 45 | "SHR", | |
| 46 | 37 | "UNM", |
| 47 | "BNOT", | |
| 48 | 38 | "NOT", |
| 49 | 39 | "LEN", |
| 50 | 40 | "CONCAT", |
| r242899 | r242900 | |
| 89 | 79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ |
| 90 | 80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ |
| 91 | 81 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ |
| 82 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ | |
| 92 | 83 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ |
| 93 | 84 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ |
| 94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ | |
| 95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ | |
| 96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ | |
| 97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ | |
| 98 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ | |
| 99 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ | |
| 100 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ | |
| 101 | 85 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ |
| 102 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ | |
| 103 | 86 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ |
| 104 | 87 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ |
| 105 | 88 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.14 | |
| 2 | ** $Id: lopcodes.h,v 1.142.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Opcodes for Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 14 | 14 | We assume that instructions are unsigned numbers. |
| 15 | 15 | All instructions have an opcode in the first 6 bits. |
| 16 | 16 | Instructions can have the following fields: |
| 17 | 'A' : 8 bits | |
| 18 | 'B' : 9 bits | |
| 19 | 'C' : 9 bits | |
| 17 | `A' : 8 bits | |
| 18 | `B' : 9 bits | |
| 19 | `C' : 9 bits | |
| 20 | 20 | 'Ax' : 26 bits ('A', 'B', and 'C' together) |
| 21 | 'Bx' : 18 bits ('B' and 'C' together) | |
| 22 | 'sBx' : signed Bx | |
| 21 | `Bx' : 18 bits (`B' and `C' together) | |
| 22 | `sBx' : signed Bx | |
| 23 | 23 | |
| 24 | 24 | A signed argument is represented in excess K; that is, the number |
| 25 | 25 | value is the unsigned value minus K. K is exactly the maximum value |
| r242899 | r242900 | |
| 58 | 58 | */ |
| 59 | 59 | #if SIZE_Bx < LUAI_BITSINT-1 |
| 60 | 60 | #define MAXARG_Bx ((1<<SIZE_Bx)-1) |
| 61 | #define MAXARG_sBx (MAXARG_Bx>>1) /* | |
| 61 | #define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */ | |
| 62 | 62 | #else |
| 63 | 63 | #define MAXARG_Bx MAX_INT |
| 64 | 64 | #define MAXARG_sBx MAX_INT |
| r242899 | r242900 | |
| 76 | 76 | #define MAXARG_C ((1<<SIZE_C)-1) |
| 77 | 77 | |
| 78 | 78 | |
| 79 | /* creates a mask with | |
| 79 | /* creates a mask with `n' 1 bits at position `p' */ | |
| 80 | 80 | #define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p)) |
| 81 | 81 | |
| 82 | /* creates a mask with | |
| 82 | /* creates a mask with `n' 0 bits at position `p' */ | |
| 83 | 83 | #define MASK0(n,p) (~MASK1(n,p)) |
| 84 | 84 | |
| 85 | 85 | /* |
| r242899 | r242900 | |
| 187 | 187 | OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ |
| 188 | 188 | OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ |
| 189 | 189 | OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ |
| 190 | OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ | |
| 190 | 191 | OP_MOD,/* A B C R(A) := RK(B) % RK(C) */ |
| 191 | 192 | 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) */ | |
| 199 | 193 | OP_UNM,/* A B R(A) := -R(B) */ |
| 200 | OP_BNOT,/* A B R(A) := ~R(B) */ | |
| 201 | 194 | OP_NOT,/* A B R(A) := not R(B) */ |
| 202 | 195 | OP_LEN,/* A B R(A) := length of R(B) */ |
| 203 | 196 | |
| 204 | 197 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ |
| 205 | 198 | |
| 206 | OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A | |
| 199 | OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */ | |
| 207 | 200 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ |
| 208 | 201 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ |
| 209 | 202 | OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ |
| r242899 | r242900 | |
| 238 | 231 | |
| 239 | 232 | /*=========================================================================== |
| 240 | 233 | Notes: |
| 241 | (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then | |
| 234 | (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then `top' is | |
| 242 | 235 | set to last_result+1, so next open instruction (OP_CALL, OP_RETURN, |
| 243 | OP_SETLIST) may use | |
| 236 | OP_SETLIST) may use `top'. | |
| 244 | 237 | |
| 245 | 238 | (*) In OP_VARARG, if (B == 0) then use actual number of varargs and |
| 246 | 239 | set top (like in OP_CALL with C == 0). |
| 247 | 240 | |
| 248 | (*) In OP_RETURN, if (B == 0) then return up to | |
| 241 | (*) In OP_RETURN, if (B == 0) then return up to `top'. | |
| 249 | 242 | |
| 250 | (*) In OP_SETLIST, if (B == 0) then B = | |
| 243 | (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next | |
| 251 | 244 | 'instruction' is EXTRAARG(real C). |
| 252 | 245 | |
| 253 | 246 | (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. |
| r242899 | r242900 | |
| 255 | 248 | (*) For comparisons, A specifies what condition the test should accept |
| 256 | 249 | (true or false). |
| 257 | 250 | |
| 258 | (*) All | |
| 251 | (*) All `skips' (pc++) assume that next instruction is a jump. | |
| 259 | 252 | |
| 260 | 253 | ===========================================================================*/ |
| 261 | 254 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: loslib.c,v 1. | |
| 2 | ** $Id: loslib.c,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Standard Operating System library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define loslib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <errno.h> |
| 14 | 9 | #include <locale.h> |
| 15 | 10 | #include <stdlib.h> |
| 16 | 11 | #include <string.h> |
| 17 | 12 | #include <time.h> |
| 18 | 13 | |
| 14 | #define loslib_c | |
| 15 | #define LUA_LIB | |
| 16 | ||
| 19 | 17 | #include "lua.h" |
| 20 | 18 | |
| 21 | 19 | #include "lauxlib.h" |
| 22 | 20 | #include "lualib.h" |
| 23 | 21 | |
| 24 | 22 | |
| 25 | #if !defined(LUA_STRFTIMEOPTIONS) /* { */ | |
| 26 | 23 | /* |
| 27 | 24 | ** list of valid conversion specifiers for the 'strftime' function |
| 28 | 25 | */ |
| 26 | #if !defined(LUA_STRFTIMEOPTIONS) | |
| 29 | 27 | |
| 30 | #if defined(LUA_USE_ | |
| 28 | #if !defined(LUA_USE_POSIX) | |
| 31 | 29 | #define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } |
| 32 | #else | |
| 30 | #else | |
| 33 | 31 | #define LUA_STRFTIMEOPTIONS \ |
| 34 | { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \ | |
| 35 | "E", "cCxXyY", \ | |
| 32 | { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \ | |
| 33 | "", "E", "cCxXyY", \ | |
| 36 | 34 | "O", "deHImMSuUVwWy" } |
| 37 | 35 | #endif |
| 38 | 36 | |
| 39 | #endif | |
| 37 | #endif | |
| 40 | 38 | |
| 41 | 39 | |
| 42 | 40 | |
| 43 | #if !defined(l_time_t) /* { */ | |
| 44 | 41 | /* |
| 45 | ** type to represent time_t in Lua | |
| 46 | */ | |
| 47 | #define l_timet lua_Integer | |
| 48 | #define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) | |
| 49 | #define l_checktime(L,a) ((time_t)luaL_checkinteger(L,a)) | |
| 50 | ||
| 51 | #endif /* } */ | |
| 52 | ||
| 53 | ||
| 54 | ||
| 55 | #if !defined(lua_tmpnam) /* { */ | |
| 56 | /* | |
| 57 | 42 | ** By default, Lua uses tmpnam except when POSIX is available, where it |
| 58 | 43 | ** uses mkstemp. |
| 59 | 44 | */ |
| 60 | ||
| 61 | #if defined(LUA_USE_POSIX) /* { */ | |
| 62 | ||
| 45 | #if defined(LUA_USE_MKSTEMP) | |
| 63 | 46 | #include <unistd.h> |
| 64 | ||
| 65 | 47 | #define LUA_TMPNAMBUFSIZE 32 |
| 66 | ||
| 67 | #if !defined(LUA_TMPNAMTEMPLATE) | |
| 68 | #define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX" | |
| 69 | #endif | |
| 70 | ||
| 71 | 48 | #define lua_tmpnam(b,e) { \ |
| 72 | strcpy(b, | |
| 49 | strcpy(b, "/tmp/lua_XXXXXX"); \ | |
| 73 | 50 | e = mkstemp(b); \ |
| 74 | 51 | if (e != -1) close(e); \ |
| 75 | 52 | e = (e == -1); } |
| 76 | 53 | |
| 77 | #el | |
| 54 | #elif !defined(lua_tmpnam) | |
| 78 | 55 | |
| 79 | /* ISO C definitions */ | |
| 80 | 56 | #define LUA_TMPNAMBUFSIZE L_tmpnam |
| 81 | 57 | #define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } |
| 82 | 58 | |
| 83 | #endif | |
| 59 | #endif | |
| 84 | 60 | |
| 85 | #endif /* } */ | |
| 86 | 61 | |
| 87 | ||
| 88 | ||
| 89 | #if !defined(l_gmtime) /* { */ | |
| 90 | 62 | /* |
| 91 | 63 | ** By default, Lua uses gmtime/localtime, except when POSIX is available, |
| 92 | 64 | ** where it uses gmtime_r/localtime_r |
| 93 | 65 | */ |
| 66 | #if defined(LUA_USE_GMTIME_R) | |
| 94 | 67 | |
| 95 | #if defined(LUA_USE_POSIX) /* { */ | |
| 96 | ||
| 97 | 68 | #define l_gmtime(t,r) gmtime_r(t,r) |
| 98 | 69 | #define l_localtime(t,r) localtime_r(t,r) |
| 99 | 70 | |
| 100 | #el | |
| 71 | #elif !defined(l_gmtime) | |
| 101 | 72 | |
| 102 | /* ISO C definitions */ | |
| 103 | #define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t)) | |
| 104 | #define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t)) | |
| 73 | #define l_gmtime(t,r) ((void)r, gmtime(t)) | |
| 74 | #define l_localtime(t,r) ((void)r, localtime(t)) | |
| 105 | 75 | |
| 106 | #endif | |
| 76 | #endif | |
| 107 | 77 | |
| 108 | #endif /* } */ | |
| 109 | 78 | |
| 110 | 79 | |
| 111 | ||
| 112 | 80 | static int os_execute (lua_State *L) { |
| 113 | 81 | const char *cmd = luaL_optstring(L, 1, NULL); |
| 114 | 82 | int stat = system(cmd); |
| r242899 | r242900 | |
| 152 | 120 | |
| 153 | 121 | |
| 154 | 122 | static int os_clock (lua_State *L) { |
| 155 | lua_pushnumber(L, ((lua_Number)( | |
| 123 | lua_pushnumber(L, ((lua_Number)(1.0*clock()))/(lua_Number)CLOCKS_PER_SEC); | |
| 156 | 124 | return 1; |
| 157 | 125 | } |
| 158 | 126 | |
| r242899 | r242900 | |
| 179 | 147 | |
| 180 | 148 | static int getboolfield (lua_State *L, const char *key) { |
| 181 | 149 | int res; |
| 182 | res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1); | |
| 150 | lua_getfield(L, -1, key); | |
| 151 | res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); | |
| 183 | 152 | lua_pop(L, 1); |
| 184 | 153 | return res; |
| 185 | 154 | } |
| r242899 | r242900 | |
| 191 | 160 | res = (int)lua_tointegerx(L, -1, &isnum); |
| 192 | 161 | if (!isnum) { |
| 193 | 162 | if (d < 0) |
| 194 | return luaL_error(L, "field | |
| 163 | return luaL_error(L, "field " LUA_QS " missing in date table", key); | |
| 195 | 164 | res = d; |
| 196 | 165 | } |
| 197 | 166 | lua_pop(L, 1); |
| r242899 | r242900 | |
| 225 | 194 | |
| 226 | 195 | static int os_date (lua_State *L) { |
| 227 | 196 | const char *s = luaL_optstring(L, 1, "%c"); |
| 228 | time_t t = luaL_opt(L, l_check | |
| 197 | time_t t = luaL_opt(L, luaL_checknumber, 2, time(NULL)); | |
| 229 | 198 | struct tm tmr, *stm; |
| 230 | 199 | if (*s == '!') { /* UTC? */ |
| 231 | 200 | stm = l_gmtime(&t, &tmr); |
| 232 | s++; /* skip | |
| 201 | s++; /* skip `!' */ | |
| 233 | 202 | } |
| 234 | 203 | else |
| 235 | 204 | stm = l_localtime(&t, &tmr); |
| r242899 | r242900 | |
| 286 | 255 | ts.tm_isdst = getboolfield(L, "isdst"); |
| 287 | 256 | t = mktime(&ts); |
| 288 | 257 | } |
| 289 | if (t != (time_t)(l_timet)t) | |
| 290 | luaL_error(L, "time result cannot be represented in this Lua instalation"); | |
| 291 | else if (t == (time_t)(-1)) | |
| 258 | if (t == (time_t)(-1)) | |
| 292 | 259 | lua_pushnil(L); |
| 293 | 260 | else |
| 294 | l_push | |
| 261 | lua_pushnumber(L, (lua_Number)t); | |
| 295 | 262 | return 1; |
| 296 | 263 | } |
| 297 | 264 | |
| 298 | 265 | |
| 299 | 266 | static int os_difftime (lua_State *L) { |
| 300 | double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2))); | |
| 301 | lua_pushnumber(L, (lua_Number)res); | |
| 267 | lua_pushnumber(L, difftime((luaL_checknumber(L, 1)), | |
| 268 | (luaL_optnumber(L, 2, 0)))); | |
| 302 | 269 | return 1; |
| 303 | 270 | } |
| 304 | 271 | |
| r242899 | r242900 | |
| 322 | 289 | if (lua_isboolean(L, 1)) |
| 323 | 290 | status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); |
| 324 | 291 | else |
| 325 | status = | |
| 292 | status = luaL_optint(L, 1, EXIT_SUCCESS); | |
| 326 | 293 | if (lua_toboolean(L, 2)) |
| 327 | 294 | lua_close(L); |
| 328 | 295 | if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.1 | |
| 2 | ** $Id: lparser.c,v 2.130.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lua Parser |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lparser_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <string.h> |
| 14 | 9 | |
| 10 | #define lparser_c | |
| 11 | #define LUA_CORE | |
| 12 | ||
| 15 | 13 | #include "lua.h" |
| 16 | 14 | |
| 17 | 15 | #include "lcode.h" |
| r242899 | r242900 | |
| 37 | 35 | #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) |
| 38 | 36 | |
| 39 | 37 | |
| 40 | /* because all strings are unified by the scanner, the parser | |
| 41 | can use pointer equality for string equality */ | |
| 42 | #define eqstr(a,b) ((a) == (b)) | |
| 43 | 38 | |
| 44 | ||
| 45 | 39 | /* |
| 46 | 40 | ** nodes for block list (list of active blocks) |
| 47 | 41 | */ |
| 48 | 42 | typedef struct BlockCnt { |
| 49 | 43 | struct BlockCnt *previous; /* chain */ |
| 50 | int firstlabel; /* index of first label in this block */ | |
| 51 | int firstgoto; /* index of first pending goto in this block */ | |
| 44 | short firstlabel; /* index of first label in this block */ | |
| 45 | short firstgoto; /* index of first pending goto in this block */ | |
| 52 | 46 | lu_byte nactvar; /* # active locals outside the block */ |
| 53 | 47 | lu_byte upval; /* true if some variable in the block is an upvalue */ |
| 54 | lu_byte isloop; /* true if | |
| 48 | lu_byte isloop; /* true if `block' is a loop */ | |
| 55 | 49 | } BlockCnt; |
| 56 | 50 | |
| 57 | 51 | |
| r242899 | r242900 | |
| 63 | 57 | static void expr (LexState *ls, expdesc *v); |
| 64 | 58 | |
| 65 | 59 | |
| 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 | ||
| 66 | 70 | /* semantic error */ |
| 67 | 71 | static l_noret semerror (LexState *ls, const char *msg) { |
| 68 | ls->t.token = 0; /* remove | |
| 72 | ls->t.token = 0; /* remove 'near to' from final message */ | |
| 69 | 73 | luaX_syntaxerror(ls, msg); |
| 70 | 74 | } |
| 71 | 75 | |
| r242899 | r242900 | |
| 218 | 222 | int i; |
| 219 | 223 | Upvaldesc *up = fs->f->upvalues; |
| 220 | 224 | for (i = 0; i < fs->nups; i++) { |
| 221 | if (eqstr(up[i].name, name)) return i; | |
| 225 | if (luaS_eqstr(up[i].name, name)) return i; | |
| 222 | 226 | } |
| 223 | 227 | return -1; /* not found */ |
| 224 | 228 | } |
| r242899 | r242900 | |
| 242 | 246 | static int searchvar (FuncState *fs, TString *n) { |
| 243 | 247 | int i; |
| 244 | 248 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { |
| 245 | if (eqstr(n, getlocvar(fs, i)->varname)) | |
| 249 | if (luaS_eqstr(n, getlocvar(fs, i)->varname)) | |
| 246 | 250 | return i; |
| 247 | 251 | } |
| 248 | 252 | return -1; /* not found */ |
| r242899 | r242900 | |
| 338 | 342 | FuncState *fs = ls->fs; |
| 339 | 343 | Labellist *gl = &ls->dyd->gt; |
| 340 | 344 | Labeldesc *gt = &gl->arr[g]; |
| 341 | lua_assert(eqstr(gt->name, label->name)); | |
| 345 | lua_assert(luaS_eqstr(gt->name, label->name)); | |
| 342 | 346 | if (gt->nactvar < label->nactvar) { |
| 343 | 347 | TString *vname = getlocvar(fs, gt->nactvar)->varname; |
| 344 | 348 | const char *msg = luaO_pushfstring(ls->L, |
| 345 | "<goto %s> at line %d jumps into the scope of local | |
| 349 | "<goto %s> at line %d jumps into the scope of local " LUA_QS, | |
| 346 | 350 | getstr(gt->name), gt->line, getstr(vname)); |
| 347 | 351 | semerror(ls, msg); |
| 348 | 352 | } |
| r242899 | r242900 | |
| 365 | 369 | /* check labels in current block for a match */ |
| 366 | 370 | for (i = bl->firstlabel; i < dyd->label.n; i++) { |
| 367 | 371 | Labeldesc *lb = &dyd->label.arr[i]; |
| 368 | if (eqstr(lb->name, gt->name)) { /* correct label? */ | |
| 372 | if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ | |
| 369 | 373 | if (gt->nactvar > lb->nactvar && |
| 370 | 374 | (bl->upval || dyd->label.n > bl->firstlabel)) |
| 371 | 375 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); |
| r242899 | r242900 | |
| 386 | 390 | l->arr[n].line = line; |
| 387 | 391 | l->arr[n].nactvar = ls->fs->nactvar; |
| 388 | 392 | l->arr[n].pc = pc; |
| 389 | l->n | |
| 393 | l->n++; | |
| 390 | 394 | return n; |
| 391 | 395 | } |
| 392 | 396 | |
| r242899 | r242900 | |
| 399 | 403 | Labellist *gl = &ls->dyd->gt; |
| 400 | 404 | int i = ls->fs->bl->firstgoto; |
| 401 | 405 | while (i < gl->n) { |
| 402 | if (eqstr(gl->arr[i].name, lb->name)) | |
| 406 | if (luaS_eqstr(gl->arr[i].name, lb->name)) | |
| 403 | 407 | closegoto(ls, i, lb); |
| 404 | 408 | else |
| 405 | 409 | i++; |
| r242899 | r242900 | |
| 408 | 412 | |
| 409 | 413 | |
| 410 | 414 | /* |
| 411 | ** export pending gotos to outer level, to check them against | |
| 415 | ** "export" pending gotos to outer level, to check them against | |
| 412 | 416 | ** outer labels; if the block being exited has upvalues, and |
| 413 | 417 | ** the goto exits the scope of any variable (which can be the |
| 414 | 418 | ** upvalue), close those variables being exited. |
| r242899 | r242900 | |
| 444 | 448 | |
| 445 | 449 | |
| 446 | 450 | /* |
| 447 | ** create a label named | |
| 451 | ** create a label named "break" to resolve break statements | |
| 448 | 452 | */ |
| 449 | 453 | static void breaklabel (LexState *ls) { |
| 450 | 454 | TString *n = luaS_new(ls->L, "break"); |
| r242899 | r242900 | |
| 459 | 463 | static l_noret undefgoto (LexState *ls, Labeldesc *gt) { |
| 460 | 464 | const char *msg = isreserved(gt->name) |
| 461 | 465 | ? "<%s> at line %d not inside a loop" |
| 462 | : "no visible label | |
| 466 | : "no visible label " LUA_QS " for <goto> at line %d"; | |
| 463 | 467 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); |
| 464 | 468 | semerror(ls, msg); |
| 465 | 469 | } |
| r242899 | r242900 | |
| 521 | 525 | |
| 522 | 526 | |
| 523 | 527 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { |
| 528 | lua_State *L = ls->L; | |
| 524 | 529 | Proto *f; |
| 525 | 530 | fs->prev = ls->fs; /* linked list of funcstates */ |
| 526 | 531 | fs->ls = ls; |
| r242899 | r242900 | |
| 539 | 544 | f = fs->f; |
| 540 | 545 | f->source = ls->source; |
| 541 | 546 | 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); | |
| 542 | 551 | enterblock(fs, bl, 0); |
| 543 | 552 | } |
| 544 | 553 | |
| r242899 | r242900 | |
| 563 | 572 | f->sizeupvalues = fs->nups; |
| 564 | 573 | lua_assert(fs->bl == NULL); |
| 565 | 574 | 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 */ | |
| 566 | 578 | luaC_checkGC(L); |
| 567 | 579 | } |
| 568 | 580 | |
| r242899 | r242900 | |
| 576 | 588 | /* |
| 577 | 589 | ** check whether current token is in the follow set of a block. |
| 578 | 590 | ** 'until' closes syntactical blocks, but do not close scope, |
| 579 | ** so it | |
| 591 | ** so it handled in separate. | |
| 580 | 592 | */ |
| 581 | 593 | static int block_follow (LexState *ls, int withuntil) { |
| 582 | 594 | switch (ls->t.token) { |
| r242899 | r242900 | |
| 590 | 602 | |
| 591 | 603 | |
| 592 | 604 | static void statlist (LexState *ls) { |
| 593 | /* statlist -> { stat [ | |
| 605 | /* statlist -> { stat [`;'] } */ | |
| 594 | 606 | while (!block_follow(ls, 1)) { |
| 595 | 607 | if (ls->t.token == TK_RETURN) { |
| 596 | 608 | statement(ls); |
| r242899 | r242900 | |
| 631 | 643 | struct ConsControl { |
| 632 | 644 | expdesc v; /* last list item read */ |
| 633 | 645 | expdesc *t; /* table descriptor */ |
| 634 | int nh; /* total number of | |
| 646 | int nh; /* total number of `record' elements */ | |
| 635 | 647 | int na; /* total number of array elements */ |
| 636 | 648 | int tostore; /* number of array elements pending to be stored */ |
| 637 | 649 | }; |
| 638 | 650 | |
| 639 | 651 | |
| 640 | 652 | static void recfield (LexState *ls, struct ConsControl *cc) { |
| 641 | /* recfield -> (NAME | | |
| 653 | /* recfield -> (NAME | `['exp1`]') = exp1 */ | |
| 642 | 654 | FuncState *fs = ls->fs; |
| 643 | 655 | int reg = ls->fs->freereg; |
| 644 | 656 | expdesc key, val; |
| r242899 | r242900 | |
| 745 | 757 | |
| 746 | 758 | |
| 747 | 759 | static void parlist (LexState *ls) { |
| 748 | /* parlist -> [ param { | |
| 760 | /* parlist -> [ param { `,' param } ] */ | |
| 749 | 761 | FuncState *fs = ls->fs; |
| 750 | 762 | Proto *f = fs->f; |
| 751 | 763 | int nparams = 0; |
| 752 | 764 | f->is_vararg = 0; |
| 753 | if (ls->t.token != ')') { /* is | |
| 765 | if (ls->t.token != ')') { /* is `parlist' not empty? */ | |
| 754 | 766 | do { |
| 755 | 767 | switch (ls->t.token) { |
| 756 | 768 | case TK_NAME: { /* param -> NAME */ |
| r242899 | r242900 | |
| 758 | 770 | nparams++; |
| 759 | 771 | break; |
| 760 | 772 | } |
| 761 | case TK_DOTS: { /* param -> | |
| 773 | case TK_DOTS: { /* param -> `...' */ | |
| 762 | 774 | luaX_next(ls); |
| 763 | 775 | f->is_vararg = 1; |
| 764 | 776 | break; |
| 765 | 777 | } |
| 766 | default: luaX_syntaxerror(ls, "<name> or | |
| 778 | default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected"); | |
| 767 | 779 | } |
| 768 | 780 | } while (!f->is_vararg && testnext(ls, ',')); |
| 769 | 781 | } |
| r242899 | r242900 | |
| 774 | 786 | |
| 775 | 787 | |
| 776 | 788 | static void body (LexState *ls, expdesc *e, int ismethod, int line) { |
| 777 | /* body -> | |
| 789 | /* body -> `(' parlist `)' block END */ | |
| 778 | 790 | FuncState new_fs; |
| 779 | 791 | BlockCnt bl; |
| 780 | 792 | new_fs.f = addprototype(ls); |
| r242899 | r242900 | |
| 796 | 808 | |
| 797 | 809 | |
| 798 | 810 | static int explist (LexState *ls, expdesc *v) { |
| 799 | /* explist -> expr { | |
| 811 | /* explist -> expr { `,' expr } */ | |
| 800 | 812 | int n = 1; /* at least one expression */ |
| 801 | 813 | expr(ls, v); |
| 802 | 814 | while (testnext(ls, ',')) { |
| r242899 | r242900 | |
| 813 | 825 | expdesc args; |
| 814 | 826 | int base, nparams; |
| 815 | 827 | switch (ls->t.token) { |
| 816 | case '(': { /* funcargs -> | |
| 828 | case '(': { /* funcargs -> `(' [ explist ] `)' */ | |
| 817 | 829 | luaX_next(ls); |
| 818 | 830 | if (ls->t.token == ')') /* arg list is empty? */ |
| 819 | 831 | args.k = VVOID; |
| r242899 | r242900 | |
| 830 | 842 | } |
| 831 | 843 | case TK_STRING: { /* funcargs -> STRING */ |
| 832 | 844 | codestring(ls, &args, ls->t.seminfo.ts); |
| 833 | luaX_next(ls); /* must use | |
| 845 | luaX_next(ls); /* must use `seminfo' before `next' */ | |
| 834 | 846 | break; |
| 835 | 847 | } |
| 836 | 848 | default: { |
| r242899 | r242900 | |
| 896 | 908 | fieldsel(ls, v); |
| 897 | 909 | break; |
| 898 | 910 | } |
| 899 | case '[': { /* | |
| 911 | case '[': { /* `[' exp1 `]' */ | |
| 900 | 912 | expdesc key; |
| 901 | 913 | luaK_exp2anyregup(fs, v); |
| 902 | 914 | yindex(ls, &key); |
| 903 | 915 | luaK_indexed(fs, v, &key); |
| 904 | 916 | break; |
| 905 | 917 | } |
| 906 | case ':': { /* | |
| 918 | case ':': { /* `:' NAME funcargs */ | |
| 907 | 919 | expdesc key; |
| 908 | 920 | luaX_next(ls); |
| 909 | 921 | checkname(ls, &key); |
| r242899 | r242900 | |
| 923 | 935 | |
| 924 | 936 | |
| 925 | 937 | static void simpleexp (LexState *ls, expdesc *v) { |
| 926 | /* simpleexp -> | |
| 938 | /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | | |
| 927 | 939 | constructor | FUNCTION body | suffixedexp */ |
| 928 | 940 | switch (ls->t.token) { |
| 929 | case TK_FLT: { | |
| 930 | init_exp(v, VKFLT, 0); | |
| 941 | case TK_NUMBER: { | |
| 942 | init_exp(v, VKNUM, 0); | |
| 931 | 943 | v->u.nval = ls->t.seminfo.r; |
| 932 | 944 | break; |
| 933 | 945 | } |
| 934 | case TK_INT: { | |
| 935 | init_exp(v, VKINT, 0); | |
| 936 | v->u.ival = ls->t.seminfo.i; | |
| 937 | break; | |
| 938 | } | |
| 939 | 946 | case TK_STRING: { |
| 940 | 947 | codestring(ls, v, ls->t.seminfo.ts); |
| 941 | 948 | break; |
| r242899 | r242900 | |
| 955 | 962 | case TK_DOTS: { /* vararg */ |
| 956 | 963 | FuncState *fs = ls->fs; |
| 957 | 964 | check_condition(ls, fs->f->is_vararg, |
| 958 | "cannot use | |
| 965 | "cannot use " LUA_QL("...") " outside a vararg function"); | |
| 959 | 966 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); |
| 960 | 967 | break; |
| 961 | 968 | } |
| r242899 | r242900 | |
| 981 | 988 | switch (op) { |
| 982 | 989 | case TK_NOT: return OPR_NOT; |
| 983 | 990 | case '-': return OPR_MINUS; |
| 984 | case '~': return OPR_BNOT; | |
| 985 | 991 | case '#': return OPR_LEN; |
| 986 | 992 | default: return OPR_NOUNOPR; |
| 987 | 993 | } |
| r242899 | r242900 | |
| 993 | 999 | case '+': return OPR_ADD; |
| 994 | 1000 | case '-': return OPR_SUB; |
| 995 | 1001 | case '*': return OPR_MUL; |
| 1002 | case '/': return OPR_DIV; | |
| 996 | 1003 | case '%': return OPR_MOD; |
| 997 | 1004 | case '^': return OPR_POW; |
| 998 | case '/': return OPR_DIV; | |
| 999 | case TK_IDIV: return OPR_IDIV; | |
| 1000 | case '&': return OPR_BAND; | |
| 1001 | case '|': return OPR_BOR; | |
| 1002 | case '~': return OPR_BXOR; | |
| 1003 | case TK_SHL: return OPR_SHL; | |
| 1004 | case TK_SHR: return OPR_SHR; | |
| 1005 | 1005 | case TK_CONCAT: return OPR_CONCAT; |
| 1006 | 1006 | case TK_NE: return OPR_NE; |
| 1007 | 1007 | case TK_EQ: return OPR_EQ; |
| r242899 | r242900 | |
| 1020 | 1020 | lu_byte left; /* left priority for each binary operator */ |
| 1021 | 1021 | lu_byte right; /* right priority */ |
| 1022 | 1022 | } priority[] = { /* ORDER OPR */ |
| 1023 | {10, 10}, {10, 10}, /* '+' '-' */ | |
| 1024 | {11, 11}, {11, 11}, /* '*' '%' */ | |
| 1025 | {14, 13}, /* '^' (right associative) */ | |
| 1026 | {11, 11}, {11, 11}, /* '/' '//' */ | |
| 1027 | {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ | |
| 1028 | {7, 7}, {7, 7}, /* '<<' '>>' */ | |
| 1029 | {9, 8}, /* '..' (right associative) */ | |
| 1030 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ | |
| 1031 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ | |
| 1032 | {2, 2}, {1, 1} /* and, or */ | |
| 1023 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */ | |
| 1024 | {10, 9}, {5, 4}, /* ^, .. (right associative) */ | |
| 1025 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ | |
| 1026 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ | |
| 1027 | {2, 2}, {1, 1} /* and, or */ | |
| 1033 | 1028 | }; |
| 1034 | 1029 | |
| 1035 | #define UNARY_PRIORITY | |
| 1030 | #define UNARY_PRIORITY 8 /* priority for unary operators */ | |
| 1036 | 1031 | |
| 1037 | 1032 | |
| 1038 | 1033 | /* |
| 1039 | 1034 | ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } |
| 1040 | ** where | |
| 1035 | ** where `binop' is any binary operator with a priority higher than `limit' | |
| 1041 | 1036 | */ |
| 1042 | 1037 | static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { |
| 1043 | 1038 | BinOpr op; |
| r242899 | r242900 | |
| 1051 | 1046 | luaK_prefix(ls->fs, uop, v, line); |
| 1052 | 1047 | } |
| 1053 | 1048 | else simpleexp(ls, v); |
| 1054 | /* expand while operators have priorities higher than | |
| 1049 | /* expand while operators have priorities higher than `limit' */ | |
| 1055 | 1050 | op = getbinopr(ls->t.token); |
| 1056 | 1051 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
| 1057 | 1052 | expdesc v2; |
| r242899 | r242900 | |
| 1151 | 1146 | "C levels"); |
| 1152 | 1147 | assignment(ls, &nv, nvars+1); |
| 1153 | 1148 | } |
| 1154 | else { /* assignment -> | |
| 1149 | else { /* assignment -> `=' explist */ | |
| 1155 | 1150 | int nexps; |
| 1156 | 1151 | checknext(ls, '='); |
| 1157 | 1152 | nexps = explist(ls, &e); |
| r242899 | r242900 | |
| 1175 | 1170 | /* cond -> exp */ |
| 1176 | 1171 | expdesc v; |
| 1177 | 1172 | expr(ls, &v); /* read condition */ |
| 1178 | if (v.k == VNIL) v.k = VFALSE; /* | |
| 1173 | if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ | |
| 1179 | 1174 | luaK_goiftrue(ls->fs, &v); |
| 1180 | 1175 | return v.f; |
| 1181 | 1176 | } |
| r242899 | r242900 | |
| 1200 | 1195 | static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { |
| 1201 | 1196 | int i; |
| 1202 | 1197 | for (i = fs->bl->firstlabel; i < ll->n; i++) { |
| 1203 | if (eqstr(label, ll->arr[i].name)) { | |
| 1198 | if (luaS_eqstr(label, ll->arr[i].name)) { | |
| 1204 | 1199 | const char *msg = luaO_pushfstring(fs->ls->L, |
| 1205 | "label | |
| 1200 | "label " LUA_QS " already defined on line %d", | |
| 1206 | 1201 | getstr(label), ll->arr[i].line); |
| 1207 | 1202 | semerror(fs->ls, msg); |
| 1208 | 1203 | } |
| r242899 | r242900 | |
| 1326 | 1321 | if (testnext(ls, ',')) |
| 1327 | 1322 | exp1(ls); /* optional step */ |
| 1328 | 1323 | else { /* default step = 1 */ |
| 1329 | luaK_codek(fs, fs->freereg, luaK_ | |
| 1324 | luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1)); | |
| 1330 | 1325 | luaK_reserveregs(fs, 1); |
| 1331 | 1326 | } |
| 1332 | 1327 | forbody(ls, base, line, 1, 1); |
| r242899 | r242900 | |
| 1364 | 1359 | TString *varname; |
| 1365 | 1360 | BlockCnt bl; |
| 1366 | 1361 | enterblock(fs, &bl, 1); /* scope for loop and control variables */ |
| 1367 | luaX_next(ls); /* skip | |
| 1362 | luaX_next(ls); /* skip `for' */ | |
| 1368 | 1363 | varname = str_checkname(ls); /* first variable name */ |
| 1369 | 1364 | switch (ls->t.token) { |
| 1370 | 1365 | case '=': fornum(ls, varname, line); break; |
| 1371 | 1366 | case ',': case TK_IN: forlist(ls, varname); break; |
| 1372 | default: luaX_syntaxerror(ls, " | |
| 1367 | default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); | |
| 1373 | 1368 | } |
| 1374 | 1369 | check_match(ls, TK_END, TK_FOR, line); |
| 1375 | leaveblock(fs); /* loop scope ( | |
| 1370 | leaveblock(fs); /* loop scope (`break' jumps to this point) */ | |
| 1376 | 1371 | } |
| 1377 | 1372 | |
| 1378 | 1373 | |
| r242899 | r242900 | |
| 1402 | 1397 | enterblock(fs, &bl, 0); |
| 1403 | 1398 | jf = v.f; |
| 1404 | 1399 | } |
| 1405 | statlist(ls); /* | |
| 1400 | statlist(ls); /* `then' part */ | |
| 1406 | 1401 | leaveblock(fs); |
| 1407 | 1402 | if (ls->t.token == TK_ELSE || |
| 1408 | 1403 | ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ |
| r242899 | r242900 | |
| 1419 | 1414 | while (ls->t.token == TK_ELSEIF) |
| 1420 | 1415 | test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ |
| 1421 | 1416 | if (testnext(ls, TK_ELSE)) |
| 1422 | block(ls); /* | |
| 1417 | block(ls); /* `else' part */ | |
| 1423 | 1418 | check_match(ls, TK_END, TK_IF, line); |
| 1424 | 1419 | luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ |
| 1425 | 1420 | } |
| r242899 | r242900 | |
| 1437 | 1432 | |
| 1438 | 1433 | |
| 1439 | 1434 | static void localstat (LexState *ls) { |
| 1440 | /* stat -> LOCAL NAME { | |
| 1435 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ | |
| 1441 | 1436 | int nvars = 0; |
| 1442 | 1437 | int nexps; |
| 1443 | 1438 | expdesc e; |
| r242899 | r242900 | |
| 1457 | 1452 | |
| 1458 | 1453 | |
| 1459 | 1454 | static int funcname (LexState *ls, expdesc *v) { |
| 1460 | /* funcname -> NAME {fieldsel} [ | |
| 1455 | /* funcname -> NAME {fieldsel} [`:' NAME] */ | |
| 1461 | 1456 | int ismethod = 0; |
| 1462 | 1457 | singlevar(ls, v); |
| 1463 | 1458 | while (ls->t.token == '.') |
| r242899 | r242900 | |
| 1478 | 1473 | ismethod = funcname(ls, &v); |
| 1479 | 1474 | body(ls, &b, ismethod, line); |
| 1480 | 1475 | luaK_storevar(ls->fs, &v, &b); |
| 1481 | luaK_fixline(ls->fs, line); /* definition | |
| 1476 | luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ | |
| 1482 | 1477 | } |
| 1483 | 1478 | |
| 1484 | 1479 | |
| r242899 | r242900 | |
| 1520 | 1515 | if (nret == 1) /* only one single value? */ |
| 1521 | 1516 | first = luaK_exp2anyreg(fs, &e); |
| 1522 | 1517 | else { |
| 1523 | luaK_exp2nextreg(fs, &e); /* values must go to the stack */ | |
| 1524 | first = fs->nactvar; /* return all active values */ | |
| 1518 | luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ | |
| 1519 | first = fs->nactvar; /* return all `active' values */ | |
| 1525 | 1520 | lua_assert(nret == fs->freereg - first); |
| 1526 | 1521 | } |
| 1527 | 1522 | } |
| r242899 | r242900 | |
| 1620 | 1615 | } |
| 1621 | 1616 | |
| 1622 | 1617 | |
| 1623 | LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |
| 1624 | Dyndata *dyd, const char *name, int firstchar) { | |
| 1618 | Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |
| 1619 | Dyndata *dyd, const char *name, int firstchar) { | |
| 1625 | 1620 | LexState lexstate; |
| 1626 | 1621 | FuncState funcstate; |
| 1627 | LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ | |
| 1628 | setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ | |
| 1622 | Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ | |
| 1623 | /* anchor closure (to avoid being collected) */ | |
| 1624 | setclLvalue(L, L->top, cl); | |
| 1629 | 1625 | incr_top(L); |
| 1630 | lexstate.h = luaH_new(L); /* create table for scanner */ | |
| 1631 | sethvalue(L, L->top, lexstate.h); /* anchor it */ | |
| 1632 | incr_top(L); | |
| 1633 | funcstate.f = cl->p = luaF_newproto(L); | |
| 1626 | funcstate.f = cl->l.p = luaF_newproto(L); | |
| 1634 | 1627 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ |
| 1635 | lua_assert(iswhite(funcstate.f)); /* do not need barrier here */ | |
| 1636 | 1628 | lexstate.buff = buff; |
| 1637 | 1629 | lexstate.dyd = dyd; |
| 1638 | 1630 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; |
| r242899 | r242900 | |
| 1641 | 1633 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); |
| 1642 | 1634 | /* all scopes should be correctly finished */ |
| 1643 | 1635 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); |
| 1644 | L->top--; /* remove scanner's table */ | |
| 1645 | return cl; /* closure is on the stack, too */ | |
| 1636 | return cl; /* it's on the stack too */ | |
| 1646 | 1637 | } |
| 1647 | 1638 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lparser.h,v 1.7 | |
| 2 | ** $Id: lparser.h,v 1.70.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lua Parser |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 21 | 21 | VNIL, |
| 22 | 22 | VTRUE, |
| 23 | 23 | VFALSE, |
| 24 | VK, /* info = index of constant in 'k' */ | |
| 25 | VKFLT, /* nval = numerical float value */ | |
| 26 | VKINT, /* nval = numerical integer value */ | |
| 24 | VK, /* info = index of constant in `k' */ | |
| 25 | VKNUM, /* nval = numerical value */ | |
| 27 | 26 | VNONRELOC, /* info = result register */ |
| 28 | 27 | VLOCAL, /* info = local register */ |
| 29 | 28 | VUPVAL, /* info = index of upvalue in 'upvalues' */ |
| r242899 | r242900 | |
| 47 | 46 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ |
| 48 | 47 | } ind; |
| 49 | 48 | int info; /* for generic use */ |
| 50 | lua_Number nval; /* for VKFLT */ | |
| 51 | lua_Integer ival; /* for VKINT */ | |
| 49 | lua_Number nval; /* for VKNUM */ | |
| 52 | 50 | } u; |
| 53 | int t; /* patch list of 'exit when true' */ | |
| 54 | int f; /* patch list of 'exit when false' */ | |
| 51 | int t; /* patch list of `exit when true' */ | |
| 52 | int f; /* patch list of `exit when false' */ | |
| 55 | 53 | } expdesc; |
| 56 | 54 | |
| 57 | 55 | |
| r242899 | r242900 | |
| 97 | 95 | /* state needed to generate code for a given function */ |
| 98 | 96 | typedef struct FuncState { |
| 99 | 97 | Proto *f; /* current function header */ |
| 98 | Table *h; /* table to find (and reuse) elements in `k' */ | |
| 100 | 99 | struct FuncState *prev; /* enclosing function */ |
| 101 | 100 | struct LexState *ls; /* lexical state */ |
| 102 | 101 | struct BlockCnt *bl; /* chain of current blocks */ |
| 103 | int pc; /* next position to code (equivalent to | |
| 102 | int pc; /* next position to code (equivalent to `ncode') */ | |
| 104 | 103 | int lasttarget; /* 'label' of last 'jump label' */ |
| 105 | int jpc; /* list of pending jumps to 'pc' */ | |
| 106 | int nk; /* number of elements in 'k' */ | |
| 107 | int np; /* number of elements in 'p' */ | |
| 104 | int jpc; /* list of pending jumps to `pc' */ | |
| 105 | int nk; /* number of elements in `k' */ | |
| 106 | int np; /* number of elements in `p' */ | |
| 108 | 107 | int firstlocal; /* index of first local var (in Dyndata array) */ |
| 109 | 108 | short nlocvars; /* number of elements in 'f->locvars' */ |
| 110 | 109 | lu_byte nactvar; /* number of active local variables */ |
| r242899 | r242900 | |
| 113 | 112 | } FuncState; |
| 114 | 113 | |
| 115 | 114 | |
| 116 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |
| 117 | Dyndata *dyd, const char *name, int firstchar); | |
| 115 | LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |
| 116 | Dyndata *dyd, const char *name, int firstchar); | |
| 118 | 117 | |
| 119 | 118 | |
| 120 | 119 | #endif |
| r242899 | r242900 | |
|---|---|---|
| 1 | /* | |
| 2 | ** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ | |
| 3 | ** Definitions for Lua code that must come before any other header file | |
| 4 | ** See Copyright Notice in lua.h | |
| 5 | */ | |
| 6 | ||
| 7 | #ifndef lprefix_h | |
| 8 | #define lprefix_h | |
| 9 | ||
| 10 | ||
| 11 | /* | |
| 12 | ** Allows POSIX/XSI stuff | |
| 13 | */ | |
| 14 | #if !defined(LUA_USE_C89) /* { */ | |
| 15 | ||
| 16 | #if !defined(_XOPEN_SOURCE) | |
| 17 | #define _XOPEN_SOURCE 600 | |
| 18 | #elif _XOPEN_SOURCE == 0 | |
| 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ | |
| 20 | #endif | |
| 21 | ||
| 22 | /* | |
| 23 | ** Allows manipulation of large files in gcc and some other compilers | |
| 24 | */ | |
| 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) | |
| 26 | #define _LARGEFILE_SOURCE 1 | |
| 27 | #define _FILE_OFFSET_BITS 64 | |
| 28 | #endif | |
| 29 | ||
| 30 | #endif /* } */ | |
| 31 | ||
| 32 | ||
| 33 | /* | |
| 34 | ** Windows stuff | |
| 35 | */ | |
| 36 | #if defined(_WIN32) /* { */ | |
| 37 | ||
| 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) | |
| 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ | |
| 40 | #endif | |
| 41 | ||
| 42 | #endif /* } */ | |
| 43 | ||
| 44 | #endif | |
| 45 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.12 | |
| 2 | ** $Id: lstate.c,v 2.99.1.2 2013/11/08 17:45:31 roberto Exp $ | |
| 3 | 3 | ** Global State |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lstate_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <stddef.h> |
| 14 | 9 | #include <string.h> |
| 15 | 10 | |
| 11 | #define lstate_c | |
| 12 | #define LUA_CORE | |
| 13 | ||
| 16 | 14 | #include "lua.h" |
| 17 | 15 | |
| 18 | 16 | #include "lapi.h" |
| r242899 | r242900 | |
| 32 | 30 | #define LUAI_GCPAUSE 200 /* 200% */ |
| 33 | 31 | #endif |
| 34 | 32 | |
| 33 | #if !defined(LUAI_GCMAJOR) | |
| 34 | #define LUAI_GCMAJOR 200 /* 200% */ | |
| 35 | #endif | |
| 36 | ||
| 35 | 37 | #if !defined(LUAI_GCMUL) |
| 36 | 38 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ |
| 37 | 39 | #endif |
| r242899 | r242900 | |
| 55 | 57 | ** thread state + extra space |
| 56 | 58 | */ |
| 57 | 59 | typedef struct LX { |
| 58 | lu_byte extra_[LUA_EXTRASPACE]; | |
| 60 | #if defined(LUAI_EXTRASPACE) | |
| 61 | char buff[LUAI_EXTRASPACE]; | |
| 62 | #endif | |
| 59 | 63 | lua_State l; |
| 60 | 64 | } LX; |
| 61 | 65 | |
| r242899 | r242900 | |
| 74 | 78 | |
| 75 | 79 | |
| 76 | 80 | /* |
| 77 | ** Compute an initial seed as random as possible. Rely on Address Space | |
| 78 | ** Layout Randomization (if present) to increase randomness.. | |
| 81 | ** Compute an initial seed as random as possible. In ANSI, rely on | |
| 82 | ** Address Space Layout Randomization (if present) to increase | |
| 83 | ** randomness.. | |
| 79 | 84 | */ |
| 80 | 85 | #define addbuff(b,p,e) \ |
| 81 | 86 | { size_t t = cast(size_t, e); \ |
| r242899 | r242900 | |
| 114 | 119 | } |
| 115 | 120 | |
| 116 | 121 | |
| 117 | /* | |
| 118 | ** free all CallInfo structures not in use by a thread | |
| 119 | */ | |
| 120 | 122 | void luaE_freeCI (lua_State *L) { |
| 121 | 123 | CallInfo *ci = L->ci; |
| 122 | 124 | CallInfo *next = ci->next; |
| r242899 | r242900 | |
| 128 | 130 | } |
| 129 | 131 | |
| 130 | 132 | |
| 131 | /* | |
| 132 | ** free half of the CallInfo structures not in use by a thread | |
| 133 | */ | |
| 134 | void luaE_shrinkCI (lua_State *L) { | |
| 135 | CallInfo *ci = L->ci; | |
| 136 | while (ci->next != NULL) { /* while there is 'next' */ | |
| 137 | CallInfo *next2 = ci->next->next; /* next's next */ | |
| 138 | if (next2 == NULL) break; | |
| 139 | luaM_free(L, ci->next); /* remove next */ | |
| 140 | ci->next = next2; /* remove 'next' from the list */ | |
| 141 | next2->previous = ci; | |
| 142 | ci = next2; | |
| 143 | } | |
| 144 | } | |
| 145 | ||
| 146 | ||
| 147 | 133 | static void stack_init (lua_State *L1, lua_State *L) { |
| 148 | 134 | int i; CallInfo *ci; |
| 149 | 135 | /* initialize stack array */ |
| r242899 | r242900 | |
| 177 | 163 | ** Create registry table and its predefined values |
| 178 | 164 | */ |
| 179 | 165 | static void init_registry (lua_State *L, global_State *g) { |
| 180 | TValue | |
| 166 | TValue mt; | |
| 181 | 167 | /* create registry */ |
| 182 | 168 | Table *registry = luaH_new(L); |
| 183 | 169 | sethvalue(L, &g->l_registry, registry); |
| 184 | 170 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); |
| 185 | 171 | /* registry[LUA_RIDX_MAINTHREAD] = L */ |
| 186 | setthvalue(L, &temp, L); /* temp = L */ | |
| 187 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); | |
| 172 | setthvalue(L, &mt, L); | |
| 173 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); | |
| 188 | 174 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ |
| 189 | sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */ | |
| 190 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp); | |
| 175 | sethvalue(L, &mt, luaH_new(L)); | |
| 176 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); | |
| 191 | 177 | } |
| 192 | 178 | |
| 193 | 179 | |
| 194 | 180 | /* |
| 195 | ** open parts of the state that may cause memory-allocation errors. | |
| 196 | ** ('g->version' != NULL flags that the state was completely build) | |
| 181 | ** open parts of the state that may cause memory-allocation errors | |
| 197 | 182 | */ |
| 198 | 183 | static void f_luaopen (lua_State *L, void *ud) { |
| 199 | 184 | global_State *g = G(L); |
| r242899 | r242900 | |
| 205 | 190 | luaX_init(L); |
| 206 | 191 | /* pre-create memory-error message */ |
| 207 | 192 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); |
| 208 | lua | |
| 193 | luaS_fix(g->memerrmsg); /* it should never be collected */ | |
| 209 | 194 | g->gcrunning = 1; /* allow gc */ |
| 210 | 195 | g->version = lua_version(NULL); |
| 211 | 196 | luai_userstateopen(L); |
| r242899 | r242900 | |
| 213 | 198 | |
| 214 | 199 | |
| 215 | 200 | /* |
| 216 | ** preinitialize a t | |
| 201 | ** preinitialize a state with consistent values without allocating | |
| 217 | 202 | ** any memory (to avoid errors) |
| 218 | 203 | */ |
| 219 | static void preinit_t | |
| 204 | static void preinit_state (lua_State *L, global_State *g) { | |
| 220 | 205 | G(L) = g; |
| 221 | 206 | L->stack = NULL; |
| 222 | 207 | L->ci = NULL; |
| 223 | 208 | L->stacksize = 0; |
| 224 | L->twups = L; /* thread has no upvalues */ | |
| 225 | 209 | L->errorJmp = NULL; |
| 226 | 210 | L->nCcalls = 0; |
| 227 | 211 | L->hook = NULL; |
| r242899 | r242900 | |
| 251 | 235 | |
| 252 | 236 | |
| 253 | 237 | LUA_API lua_State *lua_newthread (lua_State *L) { |
| 254 | global_State *g = G(L); | |
| 255 | 238 | lua_State *L1; |
| 256 | 239 | lua_lock(L); |
| 257 | 240 | luaC_checkGC(L); |
| 258 | /* create new thread */ | |
| 259 | L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; | |
| 260 | L1->marked = luaC_white(g); | |
| 261 | L1->tt = LUA_TTHREAD; | |
| 262 | /* link it on list 'allgc' */ | |
| 263 | L1->next = g->allgc; | |
| 264 | g->allgc = obj2gco(L1); | |
| 265 | /* anchor it on L stack */ | |
| 241 | L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; | |
| 266 | 242 | setthvalue(L, L->top, L1); |
| 267 | 243 | api_incr_top(L); |
| 268 | preinit_t | |
| 244 | preinit_state(L1, G(L)); | |
| 269 | 245 | L1->hookmask = L->hookmask; |
| 270 | 246 | L1->basehookcount = L->basehookcount; |
| 271 | 247 | L1->hook = L->hook; |
| 272 | 248 | resethookcount(L1); |
| 273 | /* initialize L1 extra space */ | |
| 274 | memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread), | |
| 275 | LUA_EXTRASPACE); | |
| 276 | 249 | luai_userstatethread(L, L1); |
| 277 | 250 | stack_init(L1, L); /* init stack */ |
| 278 | 251 | lua_unlock(L); |
| r242899 | r242900 | |
| 300 | 273 | g = &l->g; |
| 301 | 274 | L->next = NULL; |
| 302 | 275 | L->tt = LUA_TTHREAD; |
| 303 | g->currentwhite = bitmask(WHITE0BIT); | |
| 276 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); | |
| 304 | 277 | L->marked = luaC_white(g); |
| 305 | preinit_thread(L, g); | |
| 278 | g->gckind = KGC_NORMAL; | |
| 279 | preinit_state(L, g); | |
| 306 | 280 | g->frealloc = f; |
| 307 | 281 | g->ud = ud; |
| 308 | 282 | g->mainthread = L; |
| 309 | 283 | g->seed = makeseed(L); |
| 284 | g->uvhead.u.l.prev = &g->uvhead; | |
| 285 | g->uvhead.u.l.next = &g->uvhead; | |
| 310 | 286 | g->gcrunning = 0; /* no GC while building state */ |
| 311 | 287 | g->GCestimate = 0; |
| 312 | g->strt.size = g->strt.nuse = 0; | |
| 288 | g->strt.size = 0; | |
| 289 | g->strt.nuse = 0; | |
| 313 | 290 | g->strt.hash = NULL; |
| 314 | 291 | setnilvalue(&g->l_registry); |
| 315 | 292 | luaZ_initbuffer(L, &g->buff); |
| 316 | 293 | g->panic = NULL; |
| 317 | 294 | g->version = NULL; |
| 318 | 295 | g->gcstate = GCSpause; |
| 319 | g->gckind = KGC_NORMAL; | |
| 320 | g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL; | |
| 321 | g->sweepgc = NULL; | |
| 296 | g->allgc = NULL; | |
| 297 | g->finobj = NULL; | |
| 298 | g->tobefnz = NULL; | |
| 299 | g->sweepgc = g->sweepfin = NULL; | |
| 322 | 300 | g->gray = g->grayagain = NULL; |
| 323 | 301 | g->weak = g->ephemeron = g->allweak = NULL; |
| 324 | g->twups = NULL; | |
| 325 | 302 | g->totalbytes = sizeof(LG); |
| 326 | 303 | g->GCdebt = 0; |
| 327 | g->gcfinnum = 0; | |
| 328 | 304 | g->gcpause = LUAI_GCPAUSE; |
| 305 | g->gcmajorinc = LUAI_GCMAJOR; | |
| 329 | 306 | g->gcstepmul = LUAI_GCMUL; |
| 330 | 307 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; |
| 331 | 308 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.11 | |
| 2 | ** $Id: lstate.h,v 2.82.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Global State |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 16 | 16 | |
| 17 | 17 | /* |
| 18 | 18 | |
| 19 | ** Some notes about garbage-collected objects: All objects in Lua must | |
| 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: | |
| 19 | ** Some notes about garbage-collected objects: All objects in Lua must | |
| 20 | ** be kept somehow accessible until being freed. | |
| 23 | 21 | ** |
| 24 | ** 'allgc': all objects not marked for finalization; | |
| 25 | ** 'finobj': all objects marked for finalization; | |
| 26 | ** 'tobefnz': all objects ready to be finalized; | |
| 27 | ** 'fixedgc': all objects that are not to be collected (currently | |
| 28 | ** only small strings, such as reserved words). | |
| 22 | ** Lua keeps most objects linked in list g->allgc. The link uses field | |
| 23 | ** 'next' of the CommonHeader. | |
| 24 | ** | |
| 25 | ** Strings are kept in several lists headed by the array g->strt.hash. | |
| 26 | ** | |
| 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. | |
| 29 | 38 | |
| 30 | 39 | */ |
| 31 | 40 | |
| r242899 | r242900 | |
| 44 | 53 | /* kinds of Garbage Collection */ |
| 45 | 54 | #define KGC_NORMAL 0 |
| 46 | 55 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ |
| 56 | #define KGC_GEN 2 /* generational collection */ | |
| 47 | 57 | |
| 48 | 58 | |
| 49 | 59 | typedef struct stringtable { |
| 50 | TString **hash; | |
| 51 | int nuse; /* number of elements */ | |
| 60 | GCObject **hash; | |
| 61 | lu_int32 nuse; /* number of elements */ | |
| 52 | 62 | int size; |
| 53 | 63 | } stringtable; |
| 54 | 64 | |
| 55 | 65 | |
| 56 | 66 | /* |
| 57 | ** Information about a call. | |
| 58 | ** When a thread yields, 'func' is adjusted to pretend that the | |
| 59 | ** top function has only the yielded values in its stack; in that | |
| 60 | ** case, the actual 'func' value is saved in field 'extra'. | |
| 61 | ** When a function calls another with a continuation, 'extra' keeps | |
| 62 | ** the function index so that, in case of errors, the continuation | |
| 63 | ** function can be called with the correct top. | |
| 67 | ** information about a call | |
| 64 | 68 | */ |
| 65 | 69 | typedef struct CallInfo { |
| 66 | 70 | StkId func; /* function index in the stack */ |
| 67 | 71 | StkId top; /* top for this function */ |
| 68 | 72 | struct CallInfo *previous, *next; /* dynamic call link */ |
| 73 | short nresults; /* expected number of results from this function */ | |
| 74 | lu_byte callstatus; | |
| 75 | ptrdiff_t extra; | |
| 69 | 76 | union { |
| 70 | 77 | struct { /* only for Lua functions */ |
| 71 | 78 | StkId base; /* base for this function */ |
| 72 | 79 | const Instruction *savedpc; |
| 73 | 80 | } l; |
| 74 | 81 | struct { /* only for C functions */ |
| 75 | lua_KFunction k; /* continuation in case of yields */ | |
| 82 | int ctx; /* context info. in case of yields */ | |
| 83 | lua_CFunction k; /* continuation in case of yields */ | |
| 76 | 84 | ptrdiff_t old_errfunc; |
| 77 | lua_KContext ctx; /* context info. in case of yields */ | |
| 85 | lu_byte old_allowhook; | |
| 86 | lu_byte status; | |
| 78 | 87 | } c; |
| 79 | 88 | } u; |
| 80 | ptrdiff_t extra; | |
| 81 | short nresults; /* expected number of results from this function */ | |
| 82 | lu_byte callstatus; | |
| 83 | 89 | } CallInfo; |
| 84 | 90 | |
| 85 | 91 | |
| 86 | 92 | /* |
| 87 | 93 | ** Bits in CallInfo status |
| 88 | 94 | */ |
| 89 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ | |
| 90 | #define CIST_LUA (1<<1) /* call is running a Lua function */ | |
| 91 | #define CIST_HOOKED (1<<2) /* call is running a debug hook */ | |
| 92 | #define CIST_REENTRY (1<<3) /* call is running on same invocation of | |
| 95 | #define CIST_LUA (1<<0) /* call is running a Lua function */ | |
| 96 | #define CIST_HOOKED (1<<1) /* call is running a debug hook */ | |
| 97 | #define CIST_REENTRY (1<<2) /* call is running on same invocation of | |
| 93 | 98 | luaV_execute of previous call */ |
| 99 | #define CIST_YIELDED (1<<3) /* call reentered after suspension */ | |
| 94 | 100 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ |
| 95 | #define CIST_TAIL (1<<5) /* call was tail called */ | |
| 96 | #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ | |
| 101 | #define CIST_STAT (1<<5) /* call has an error status (pcall) */ | |
| 102 | #define CIST_TAIL (1<<6) /* call was tail called */ | |
| 103 | #define CIST_HOOKYIELD (1<<7) /* last hook called yielded */ | |
| 97 | 104 | |
| 105 | ||
| 98 | 106 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) |
| 99 | 107 | |
| 100 | /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ | |
| 101 | #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) | |
| 102 | #define getoah(st) ((st) & CIST_OAH) | |
| 103 | 108 | |
| 104 | ||
| 105 | 109 | /* |
| 106 | ** | |
| 110 | ** `global state', shared by all threads of this state | |
| 107 | 111 | */ |
| 108 | 112 | typedef struct global_State { |
| 109 | 113 | lua_Alloc frealloc; /* function to reallocate memory */ |
| 110 | void *ud; /* auxiliary data to | |
| 114 | void *ud; /* auxiliary data to `frealloc' */ | |
| 111 | 115 | lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ |
| 112 | 116 | l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ |
| 113 | 117 | lu_mem GCmemtrav; /* memory traversed by the GC */ |
| r242899 | r242900 | |
| 119 | 123 | lu_byte gcstate; /* state of garbage collector */ |
| 120 | 124 | lu_byte gckind; /* kind of GC running */ |
| 121 | 125 | lu_byte gcrunning; /* true if GC is running */ |
| 126 | int sweepstrgc; /* position of sweep in `strt' */ | |
| 122 | 127 | GCObject *allgc; /* list of all collectable objects */ |
| 123 | GCObject **sweepgc; /* current position of sweep in list */ | |
| 124 | 128 | 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' */ | |
| 125 | 131 | GCObject *gray; /* list of gray objects */ |
| 126 | 132 | GCObject *grayagain; /* list of objects to be traversed atomically */ |
| 127 | 133 | GCObject *weak; /* list of tables with weak values */ |
| 128 | 134 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ |
| 129 | 135 | GCObject *allweak; /* list of all-weak tables */ |
| 130 | 136 | GCObject *tobefnz; /* list of userdata to be GC */ |
| 131 | GCObject *fixedgc; /* list of objects not to be collected */ | |
| 132 | struct lua_State *twups; /* list of threads with open upvalues */ | |
| 137 | UpVal uvhead; /* head of double-linked list of all open upvalues */ | |
| 133 | 138 | Mbuffer buff; /* temporary buffer for string concatenation */ |
| 134 | unsigned int gcfinnum; /* number of finalizers to call in each GC step */ | |
| 135 | 139 | int gcpause; /* size of pause between successive GCs */ |
| 136 | int gcstepmul; /* GC 'granularity' */ | |
| 140 | int gcmajorinc; /* pause between major collections (only in gen. mode) */ | |
| 141 | int gcstepmul; /* GC `granularity' */ | |
| 137 | 142 | lua_CFunction panic; /* to be called in unprotected errors */ |
| 138 | 143 | struct lua_State *mainthread; |
| 139 | 144 | const lua_Number *version; /* pointer to version number */ |
| r242899 | r242900 | |
| 144 | 149 | |
| 145 | 150 | |
| 146 | 151 | /* |
| 147 | ** | |
| 152 | ** `per thread' state | |
| 148 | 153 | */ |
| 149 | 154 | struct lua_State { |
| 150 | 155 | CommonHeader; |
| r242899 | r242900 | |
| 155 | 160 | const Instruction *oldpc; /* last pc traced */ |
| 156 | 161 | StkId stack_last; /* last free slot in the stack */ |
| 157 | 162 | StkId stack; /* stack base */ |
| 158 | UpVal *openupval; /* list of open upvalues in this stack */ | |
| 159 | GCObject *gclist; | |
| 160 | struct lua_State *twups; /* list of threads with open upvalues */ | |
| 161 | struct lua_longjmp *errorJmp; /* current error recover point */ | |
| 162 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ | |
| 163 | lua_Hook hook; | |
| 164 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | |
| 165 | 163 | int stacksize; |
| 166 | int basehookcount; | |
| 167 | int hookcount; | |
| 168 | 164 | unsigned short nny; /* number of non-yieldable calls in stack */ |
| 169 | 165 | unsigned short nCcalls; /* number of nested C calls */ |
| 170 | 166 | lu_byte hookmask; |
| 171 | 167 | lu_byte allowhook; |
| 168 | int basehookcount; | |
| 169 | int hookcount; | |
| 170 | lua_Hook hook; | |
| 171 | GCObject *openupval; /* list of open upvalues in this stack */ | |
| 172 | GCObject *gclist; | |
| 173 | struct lua_longjmp *errorJmp; /* current error recover point */ | |
| 174 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | |
| 175 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ | |
| 172 | 176 | }; |
| 173 | 177 | |
| 174 | 178 | |
| r242899 | r242900 | |
| 176 | 180 | |
| 177 | 181 | |
| 178 | 182 | /* |
| 179 | ** Union of all collectable objects | |
| 183 | ** Union of all collectable objects | |
| 180 | 184 | */ |
| 181 | union GCUnion { | |
| 182 | GCObject gc; /* common header */ | |
| 183 | struct TString ts; | |
| 184 | struct Udata u; | |
| 185 | union GCObject { | |
| 186 | GCheader gch; /* common header */ | |
| 187 | union TString ts; | |
| 188 | union Udata u; | |
| 185 | 189 | union Closure cl; |
| 186 | 190 | struct Table h; |
| 187 | 191 | struct Proto p; |
| 192 | struct UpVal uv; | |
| 188 | 193 | struct lua_State th; /* thread */ |
| 189 | 194 | }; |
| 190 | 195 | |
| 191 | 196 | |
| 192 | #define c | |
| 197 | #define gch(o) (&(o)->gch) | |
| 193 | 198 | |
| 194 | 199 | /* macros to convert a GCObject into a specific value */ |
| 195 | #define gco2ts(o) \ | |
| 196 | check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) | |
| 197 | #define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) | |
| 198 | #define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l)) | |
| 199 | #define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c)) | |
| 200 | #define rawgco2ts(o) \ | |
| 201 | check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts)) | |
| 202 | #define gco2ts(o) (&rawgco2ts(o)->tsv) | |
| 203 | #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) | |
| 204 | #define gco2u(o) (&rawgco2u(o)->uv) | |
| 205 | #define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l)) | |
| 206 | #define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c)) | |
| 200 | 207 | #define gco2cl(o) \ |
| 201 | check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) | |
| 202 | #define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) | |
| 203 | #define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p)) | |
| 204 | #define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th)) | |
| 208 | check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) | |
| 209 | #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)) | |
| 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)) | |
| 205 | 213 | |
| 214 | /* macro to convert any Lua object into a GCObject */ | |
| 215 | #define obj2gco(v) (cast(GCObject *, (v))) | |
| 206 | 216 | |
| 207 | /* macro to convert a Lua object into a GCObject */ | |
| 208 | #define obj2gco(v) \ | |
| 209 | check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc))) | |
| 210 | 217 | |
| 211 | ||
| 212 | 218 | /* actual number of total bytes allocated */ |
| 213 | 219 | #define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) |
| 214 | 220 | |
| r242899 | r242900 | |
| 216 | 222 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); |
| 217 | 223 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
| 218 | 224 | LUAI_FUNC void luaE_freeCI (lua_State *L); |
| 219 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); | |
| 220 | 225 | |
| 221 | 226 | |
| 222 | 227 | #endif |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lstring.c,v 2. | |
| 2 | ** $Id: lstring.c,v 2.26.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | ||
| 8 | #include <string.h> | |
| 9 | ||
| 7 | 10 | #define lstring_c |
| 8 | 11 | #define LUA_CORE |
| 9 | 12 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <string.h> | |
| 14 | ||
| 15 | 13 | #include "lua.h" |
| 16 | 14 | |
| 17 | #include "ldebug.h" | |
| 18 | #include "ldo.h" | |
| 19 | 15 | #include "lmem.h" |
| 20 | 16 | #include "lobject.h" |
| 21 | 17 | #include "lstate.h" |
| 22 | 18 | #include "lstring.h" |
| 23 | 19 | |
| 24 | 20 | |
| 25 | ||
| 26 | 21 | /* |
| 27 | 22 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to |
| 28 | 23 | ** compute its hash |
| r242899 | r242900 | |
| 36 | 31 | ** equality for long strings |
| 37 | 32 | */ |
| 38 | 33 | int luaS_eqlngstr (TString *a, TString *b) { |
| 39 | size_t len = a->len; | |
| 40 | lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); | |
| 34 | size_t len = a->tsv.len; | |
| 35 | lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); | |
| 41 | 36 | return (a == b) || /* same instance or... */ |
| 42 | ((len == b->len) && /* equal length and ... */ | |
| 37 | ((len == b->tsv.len) && /* equal length and ... */ | |
| 43 | 38 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ |
| 44 | 39 | } |
| 45 | 40 | |
| 46 | 41 | |
| 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 | ||
| 47 | 51 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { |
| 48 | 52 | unsigned int h = seed ^ cast(unsigned int, l); |
| 49 | 53 | size_t l1; |
| r242899 | r242900 | |
| 60 | 64 | void luaS_resize (lua_State *L, int newsize) { |
| 61 | 65 | int i; |
| 62 | 66 | stringtable *tb = &G(L)->strt; |
| 63 | if (newsize > tb->size) { /* grow table if needed */ | |
| 64 | luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); | |
| 65 | for (i = tb->size; i < newsize; i++) | |
| 66 | tb->hash[i] = NULL; | |
| 67 | /* cannot resize while GC is traversing strings */ | |
| 68 | luaC_runtilstate(L, ~bitmask(GCSsweepstring)); | |
| 69 | if (newsize > tb->size) { | |
| 70 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); | |
| 71 | for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; | |
| 67 | 72 | } |
| 68 | for (i = 0; i < tb->size; i++) { /* rehash */ | |
| 69 | TString *p = tb->hash[i]; | |
| 73 | /* rehash */ | |
| 74 | for (i=0; i<tb->size; i++) { | |
| 75 | GCObject *p = tb->hash[i]; | |
| 70 | 76 | tb->hash[i] = NULL; |
| 71 | 77 | while (p) { /* for each node in the list */ |
| 72 | TString *hnext = p->hnext; /* save next */ | |
| 73 | unsigned int h = lmod(p->hash, newsize); /* new position */ | |
| 74 | p->hnext = tb->hash[h]; /* chain it */ | |
| 78 | GCObject *next = gch(p)->next; /* save next */ | |
| 79 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ | |
| 80 | gch(p)->next = tb->hash[h]; /* chain it */ | |
| 75 | 81 | tb->hash[h] = p; |
| 76 | p = hnext; | |
| 82 | resetoldbit(p); /* see MOVE OLD rule */ | |
| 83 | p = next; | |
| 77 | 84 | } |
| 78 | 85 | } |
| 79 | if (newsize < tb->size) { /* shrink table if needed */ | |
| 80 | /* vanishing slice should be empty */ | |
| 86 | if (newsize < tb->size) { | |
| 87 | /* shrinking slice must be empty */ | |
| 81 | 88 | lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); |
| 82 | luaM_reallocvector(L, tb->hash, tb->size, newsize, | |
| 89 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); | |
| 83 | 90 | } |
| 84 | 91 | tb->size = newsize; |
| 85 | 92 | } |
| 86 | 93 | |
| 87 | 94 | |
| 88 | ||
| 89 | 95 | /* |
| 90 | 96 | ** creates a new string object |
| 91 | 97 | */ |
| 92 | 98 | static TString *createstrobj (lua_State *L, const char *str, size_t l, |
| 93 | int tag, unsigned int h) { | |
| 99 | int tag, unsigned int h, GCObject **list) { | |
| 94 | 100 | TString *ts; |
| 95 | GCObject *o; | |
| 96 | 101 | size_t totalsize; /* total size of TString object */ |
| 97 | totalsize = sizelstring(l); | |
| 98 | o = luaC_newobj(L, tag, totalsize); | |
| 99 | ts = gco2ts(o); | |
| 100 | ts->len = l; | |
| 101 | ts->hash = h; | |
| 102 | ts->extra = 0; | |
| 103 | memcpy(getaddrstr(ts), str, l * sizeof(char)); | |
| 104 | getaddrstr(ts)[l] = '\0'; /* ending 0 */ | |
| 102 | totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); | |
| 103 | ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; | |
| 104 | ts->tsv.len = l; | |
| 105 | ts->tsv.hash = h; | |
| 106 | ts->tsv.extra = 0; | |
| 107 | memcpy(ts+1, str, l*sizeof(char)); | |
| 108 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ | |
| 105 | 109 | return ts; |
| 106 | 110 | } |
| 107 | 111 | |
| 108 | 112 | |
| 109 | void luaS_remove (lua_State *L, TString *ts) { | |
| 113 | /* | |
| 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 */ | |
| 110 | 119 | stringtable *tb = &G(L)->strt; |
| 111 | TString **p = &tb->hash[lmod(ts->hash, tb->size)]; | |
| 112 | while (*p != ts) /* find previous element */ | |
| 113 | p = &(*p)->hnext; | |
| 114 | *p = (*p)->hnext; /* remove element from its list */ | |
| 115 | tb->nuse--; | |
| 120 | TString *s; | |
| 121 | if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) | |
| 122 | luaS_resize(L, tb->size*2); /* too crowded */ | |
| 123 | list = &tb->hash[lmod(h, tb->size)]; | |
| 124 | s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); | |
| 125 | tb->nuse++; | |
| 126 | return s; | |
| 116 | 127 | } |
| 117 | 128 | |
| 118 | 129 | |
| r242899 | r242900 | |
| 120 | 131 | ** checks whether short string exists and reuses it or creates a new one |
| 121 | 132 | */ |
| 122 | 133 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { |
| 123 | | |
| 134 | GCObject *o; | |
| 124 | 135 | global_State *g = G(L); |
| 125 | 136 | unsigned int h = luaS_hash(str, l, g->seed); |
| 126 | TString **list = &g->strt.hash[lmod(h, g->strt.size)]; | |
| 127 | for (ts = *list; ts != NULL; ts = ts->hnext) { | |
| 128 | if (l == ts->len && | |
| 137 | for (o = g->strt.hash[lmod(h, g->strt.size)]; | |
| 138 | o != NULL; | |
| 139 | o = gch(o)->next) { | |
| 140 | TString *ts = rawgco2ts(o); | |
| 141 | if (h == ts->tsv.hash && | |
| 142 | l == ts->tsv.len && | |
| 129 | 143 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { |
| 130 | /* found! */ | |
| 131 | if (isdead(g, ts)) /* dead (but not collected yet)? */ | |
| 132 | changewhite(ts); /* resurrect it */ | |
| 144 | if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ | |
| 145 | changewhite(o); /* resurrect it */ | |
| 133 | 146 | return ts; |
| 134 | 147 | } |
| 135 | 148 | } |
| 136 | if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) { | |
| 137 | luaS_resize(L, g->strt.size * 2); | |
| 138 | list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ | |
| 139 | } | |
| 140 | ts = createstrobj(L, str, l, LUA_TSHRSTR, h); | |
| 141 | ts->hnext = *list; | |
| 142 | *list = ts; | |
| 143 | g->strt.nuse++; | |
| 144 | return ts; | |
| 149 | return newshrstr(L, str, l, h); /* not found; create a new string */ | |
| 145 | 150 | } |
| 146 | 151 | |
| 147 | 152 | |
| r242899 | r242900 | |
| 152 | 157 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ |
| 153 | 158 | return internshrstr(L, str, l); |
| 154 | 159 | else { |
| 155 | if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char)) | |
| 160 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) | |
| 156 | 161 | luaM_toobig(L); |
| 157 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed); | |
| 162 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); | |
| 158 | 163 | } |
| 159 | 164 | } |
| 160 | 165 | |
| r242899 | r242900 | |
| 167 | 172 | } |
| 168 | 173 | |
| 169 | 174 | |
| 170 | Udata *luaS_newudata (lua_State *L, size_t s) { | |
| 175 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { | |
| 171 | 176 | Udata *u; |
| 172 | GCObject *o; | |
| 173 | if (s > MAX_SIZE - sizeof(Udata)) | |
| 177 | if (s > MAX_SIZET - sizeof(Udata)) | |
| 174 | 178 | luaM_toobig(L); |
| 175 | o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s)); | |
| 176 | u = gco2u(o); | |
| 177 | u->len = s; | |
| 178 | u->metatable = NULL; | |
| 179 | setuservalue(L, u, luaO_nilobject); | |
| 179 | u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; | |
| 180 | u->uv.len = s; | |
| 181 | u->uv.metatable = NULL; | |
| 182 | u->uv.env = e; | |
| 180 | 183 | return u; |
| 181 | 184 | } |
| 182 | 185 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lstring.h,v 1. | |
| 2 | ** $Id: lstring.h,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** String table (keep all strings handled by Lua) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 12 | 12 | #include "lstate.h" |
| 13 | 13 | |
| 14 | 14 | |
| 15 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) | |
| 16 | #define sizestring(s) sizelstring((s)->len) | |
| 15 | #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) | |
| 17 | 16 | |
| 18 | #define sizeludata(l) (sizeof(union UUdata) + (l)) | |
| 19 | #define sizeudata(u) sizeludata((u)->len) | |
| 17 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) | |
| 20 | 18 | |
| 21 | 19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ |
| 22 | 20 | (sizeof(s)/sizeof(char))-1)) |
| 23 | 21 | |
| 22 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) | |
| 24 | 23 | |
| 24 | ||
| 25 | 25 | /* |
| 26 | 26 | ** test whether a string is a reserved word |
| 27 | 27 | */ |
| 28 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) | |
| 28 | #define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) | |
| 29 | 29 | |
| 30 | 30 | |
| 31 | 31 | /* |
| 32 | 32 | ** equality for short strings, which are always internalized |
| 33 | 33 | */ |
| 34 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) | |
| 34 | #define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) | |
| 35 | 35 | |
| 36 | 36 | |
| 37 | 37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); |
| 38 | 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); |
| 39 | LUAI_FUNC int luaS_eqstr (TString *a, TString *b); | |
| 39 | 40 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
| 40 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); | |
| 41 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); | |
| 41 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); | |
| 42 | 42 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); |
| 43 | 43 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); |
| 44 | 44 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1. | |
| 2 | ** $Id: lstrlib.c,v 1.178.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Standard library for string operations and pattern-matching |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lstrlib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <ctype.h> |
| 14 | #include <limits.h> | |
| 15 | 9 | #include <stddef.h> |
| 16 | 10 | #include <stdio.h> |
| 17 | 11 | #include <stdlib.h> |
| 18 | 12 | #include <string.h> |
| 19 | 13 | |
| 14 | #define lstrlib_c | |
| 15 | #define LUA_LIB | |
| 16 | ||
| 20 | 17 | #include "lua.h" |
| 21 | 18 | |
| 22 | 19 | #include "lauxlib.h" |
| r242899 | r242900 | |
| 32 | 29 | #endif |
| 33 | 30 | |
| 34 | 31 | |
| 35 | /* macro to | |
| 32 | /* macro to `unsign' a character */ | |
| 36 | 33 | #define uchar(c) ((unsigned char)(c)) |
| 37 | 34 | |
| 38 | 35 | |
| 39 | /* | |
| 40 | ** Some sizes are better limited to fit in 'int', but must also fit in | |
| 41 | ** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) | |
| 42 | */ | |
| 43 | #define MAXSIZE \ | |
| 44 | (sizeof(size_t) < sizeof(int) ? (~(size_t)0) : (size_t)(INT_MAX)) | |
| 45 | 36 | |
| 46 | ||
| 47 | ||
| 48 | ||
| 49 | 37 | static int str_len (lua_State *L) { |
| 50 | 38 | size_t l; |
| 51 | 39 | luaL_checklstring(L, 1, &l); |
| r242899 | r242900 | |
| 55 | 43 | |
| 56 | 44 | |
| 57 | 45 | /* translate a relative string position: negative means back from end */ |
| 58 | static lua_Integer posrelat (lua_Integer pos, size_t len) { | |
| 59 | if (pos >= 0) return pos; | |
| 46 | static size_t posrelat (ptrdiff_t pos, size_t len) { | |
| 47 | if (pos >= 0) return (size_t)pos; | |
| 60 | 48 | else if (0u - (size_t)pos > len) return 0; |
| 61 | else return | |
| 49 | else return len - ((size_t)-pos) + 1; | |
| 62 | 50 | } |
| 63 | 51 | |
| 64 | 52 | |
| 65 | 53 | static int str_sub (lua_State *L) { |
| 66 | 54 | size_t l; |
| 67 | 55 | const char *s = luaL_checklstring(L, 1, &l); |
| 68 | lua_Integer start = posrelat(luaL_checkinteger(L, 2), l); | |
| 69 | lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l); | |
| 56 | size_t start = posrelat(luaL_checkinteger(L, 2), l); | |
| 57 | size_t end = posrelat(luaL_optinteger(L, 3, -1), l); | |
| 70 | 58 | if (start < 1) start = 1; |
| 71 | if (end > | |
| 59 | if (end > l) end = l; | |
| 72 | 60 | if (start <= end) |
| 73 | lua_pushlstring(L, s + start - 1, | |
| 61 | lua_pushlstring(L, s + start - 1, end - start + 1); | |
| 74 | 62 | else lua_pushliteral(L, ""); |
| 75 | 63 | return 1; |
| 76 | 64 | } |
| r242899 | r242900 | |
| 114 | 102 | } |
| 115 | 103 | |
| 116 | 104 | |
| 105 | /* reasonable limit to avoid arithmetic overflow */ | |
| 106 | #define MAXSIZE ((~(size_t)0) >> 1) | |
| 107 | ||
| 117 | 108 | static int str_rep (lua_State *L) { |
| 118 | 109 | size_t l, lsep; |
| 119 | 110 | const char *s = luaL_checklstring(L, 1, &l); |
| 120 | | |
| 111 | int n = luaL_checkint(L, 2); | |
| 121 | 112 | const char *sep = luaL_optlstring(L, 3, "", &lsep); |
| 122 | 113 | if (n <= 0) lua_pushliteral(L, ""); |
| 123 | else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */ | |
| 114 | else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ | |
| 124 | 115 | return luaL_error(L, "resulting string too large"); |
| 125 | 116 | else { |
| 126 | size_t totallen = | |
| 117 | size_t totallen = n * l + (n - 1) * lsep; | |
| 127 | 118 | luaL_Buffer b; |
| 128 | 119 | char *p = luaL_buffinitsize(L, &b, totallen); |
| 129 | 120 | while (n-- > 1) { /* first n-1 copies (followed by separator) */ |
| 130 | 121 | memcpy(p, s, l * sizeof(char)); p += l; |
| 131 | if (lsep > 0) { /* empty 'memcpy' is not that cheap */ | |
| 132 | memcpy(p, sep, lsep * sizeof(char)); | |
| 133 | p += lsep; | |
| 122 | if (lsep > 0) { /* avoid empty 'memcpy' (may be expensive) */ | |
| 123 | memcpy(p, sep, lsep * sizeof(char)); p += lsep; | |
| 134 | 124 | } |
| 135 | 125 | } |
| 136 | 126 | memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ |
| r242899 | r242900 | |
| 143 | 133 | static int str_byte (lua_State *L) { |
| 144 | 134 | size_t l; |
| 145 | 135 | const char *s = luaL_checklstring(L, 1, &l); |
| 146 | lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l); | |
| 147 | lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l); | |
| 136 | size_t posi = posrelat(luaL_optinteger(L, 2, 1), l); | |
| 137 | size_t pose = posrelat(luaL_optinteger(L, 3, posi), l); | |
| 148 | 138 | int n, i; |
| 149 | 139 | if (posi < 1) posi = 1; |
| 150 | if (pose > | |
| 140 | if (pose > l) pose = l; | |
| 151 | 141 | if (posi > pose) return 0; /* empty interval; return no values */ |
| 152 | 142 | n = (int)(pose - posi + 1); |
| 153 | if (posi + n <= pose) /* | |
| 143 | if (posi + n <= pose) /* (size_t -> int) overflow? */ | |
| 154 | 144 | return luaL_error(L, "string slice too long"); |
| 155 | 145 | luaL_checkstack(L, n, "string slice too long"); |
| 156 | 146 | for (i=0; i<n; i++) |
| r242899 | r242900 | |
| 165 | 155 | luaL_Buffer b; |
| 166 | 156 | char *p = luaL_buffinitsize(L, &b, n); |
| 167 | 157 | for (i=1; i<=n; i++) { |
| 168 | | |
| 158 | int c = luaL_checkint(L, i); | |
| 169 | 159 | luaL_argcheck(L, uchar(c) == c, i, "value out of range"); |
| 170 | 160 | p[i - 1] = uchar(c); |
| 171 | 161 | } |
| r242899 | r242900 | |
| 174 | 164 | } |
| 175 | 165 | |
| 176 | 166 | |
| 177 | static int writer (lua_State *L, const void | |
| 167 | static int writer (lua_State *L, const void* b, size_t size, void* B) { | |
| 178 | 168 | (void)L; |
| 179 | luaL_addlstring((luaL_Buffer | |
| 169 | luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); | |
| 180 | 170 | return 0; |
| 181 | 171 | } |
| 182 | 172 | |
| 183 | 173 | |
| 184 | 174 | static int str_dump (lua_State *L) { |
| 185 | 175 | luaL_Buffer b; |
| 186 | int strip = lua_toboolean(L, 2); | |
| 187 | 176 | luaL_checktype(L, 1, LUA_TFUNCTION); |
| 188 | 177 | lua_settop(L, 1); |
| 189 | 178 | luaL_buffinit(L,&b); |
| 190 | if (lua_dump(L, writer, &b | |
| 179 | if (lua_dump(L, writer, &b) != 0) | |
| 191 | 180 | return luaL_error(L, "unable to dump given function"); |
| 192 | 181 | luaL_pushresult(&b); |
| 193 | 182 | return 1; |
| r242899 | r242900 | |
| 254 | 243 | switch (*p++) { |
| 255 | 244 | case L_ESC: { |
| 256 | 245 | if (p == ms->p_end) |
| 257 | luaL_error(ms->L, "malformed pattern (ends with | |
| 246 | luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); | |
| 258 | 247 | return p+1; |
| 259 | 248 | } |
| 260 | 249 | case '[': { |
| 261 | 250 | if (*p == '^') p++; |
| 262 | do { /* look for a | |
| 251 | do { /* look for a `]' */ | |
| 263 | 252 | if (p == ms->p_end) |
| 264 | luaL_error(ms->L, "malformed pattern (missing | |
| 253 | luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); | |
| 265 | 254 | if (*(p++) == L_ESC && p < ms->p_end) |
| 266 | p++; /* skip escapes (e.g. | |
| 255 | p++; /* skip escapes (e.g. `%]') */ | |
| 267 | 256 | } while (*p != ']'); |
| 268 | 257 | return p+1; |
| 269 | 258 | } |
| r242899 | r242900 | |
| 298 | 287 | int sig = 1; |
| 299 | 288 | if (*(p+1) == '^') { |
| 300 | 289 | sig = 0; |
| 301 | p++; /* skip the | |
| 290 | p++; /* skip the `^' */ | |
| 302 | 291 | } |
| 303 | 292 | while (++p < ec) { |
| 304 | 293 | if (*p == L_ESC) { |
| r242899 | r242900 | |
| 336 | 325 | static const char *matchbalance (MatchState *ms, const char *s, |
| 337 | 326 | const char *p) { |
| 338 | 327 | if (p >= ms->p_end - 1) |
| 339 | luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); | |
| 328 | luaL_error(ms->L, "malformed pattern " | |
| 329 | "(missing arguments to " LUA_QL("%%b") ")"); | |
| 340 | 330 | if (*s != *p) return NULL; |
| 341 | 331 | else { |
| 342 | 332 | int b = *p; |
| r242899 | r242900 | |
| 435 | 425 | break; |
| 436 | 426 | } |
| 437 | 427 | case '$': { |
| 438 | if ((p + 1) != ms->p_end) /* is the | |
| 428 | if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */ | |
| 439 | 429 | goto dflt; /* no; go to default */ |
| 440 | 430 | s = (s == ms->src_end) ? s : NULL; /* check end of string */ |
| 441 | 431 | break; |
| r242899 | r242900 | |
| 453 | 443 | const char *ep; char previous; |
| 454 | 444 | p += 2; |
| 455 | 445 | if (*p != '[') |
| 456 | luaL_error(ms->L, "missing '[' after '%%f' in pattern"); | |
| 446 | luaL_error(ms->L, "missing " LUA_QL("[") " after " | |
| 447 | LUA_QL("%%f") " in pattern"); | |
| 457 | 448 | ep = classend(ms, p); /* points to what is next */ |
| 458 | 449 | previous = (s == ms->src_init) ? '\0' : *(s - 1); |
| 459 | 450 | if (!matchbracketclass(uchar(previous), p, ep - 1) && |
| r242899 | r242900 | |
| 523 | 514 | static const char *lmemfind (const char *s1, size_t l1, |
| 524 | 515 | const char *s2, size_t l2) { |
| 525 | 516 | if (l2 == 0) return s1; /* empty strings are everywhere */ |
| 526 | else if (l2 > l1) return NULL; /* avoids a negative | |
| 517 | else if (l2 > l1) return NULL; /* avoids a negative `l1' */ | |
| 527 | 518 | else { |
| 528 | const char *init; /* to search for a '*s2' inside 's1' */ | |
| 529 | l2--; /* 1st char will be checked by 'memchr' */ | |
| 530 | l1 = l1-l2; /* 's2' cannot be found after that */ | |
| 519 | const char *init; /* to search for a `*s2' inside `s1' */ | |
| 520 | l2--; /* 1st char will be checked by `memchr' */ | |
| 521 | l1 = l1-l2; /* `s2' cannot be found after that */ | |
| 531 | 522 | while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { |
| 532 | 523 | init++; /* 1st char is already checked */ |
| 533 | 524 | if (memcmp(init, s2+1, l2) == 0) |
| 534 | 525 | return init-1; |
| 535 | else { /* correct | |
| 526 | else { /* correct `l1' and `s1' to try again */ | |
| 536 | 527 | l1 -= init-s1; |
| 537 | 528 | s1 = init; |
| 538 | 529 | } |
| r242899 | r242900 | |
| 548 | 539 | if (i == 0) /* ms->level == 0, too */ |
| 549 | 540 | lua_pushlstring(ms->L, s, e - s); /* add whole match */ |
| 550 | 541 | else |
| 551 | luaL_error(ms->L, "invalid capture index | |
| 542 | luaL_error(ms->L, "invalid capture index"); | |
| 552 | 543 | } |
| 553 | 544 | else { |
| 554 | 545 | ptrdiff_t l = ms->capture[i].len; |
| r242899 | r242900 | |
| 587 | 578 | size_t ls, lp; |
| 588 | 579 | const char *s = luaL_checklstring(L, 1, &ls); |
| 589 | 580 | const char *p = luaL_checklstring(L, 2, &lp); |
| 590 | | |
| 581 | size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); | |
| 591 | 582 | if (init < 1) init = 1; |
| 592 | else if (init > | |
| 583 | else if (init > ls + 1) { /* start after string's end? */ | |
| 593 | 584 | lua_pushnil(L); /* cannot find anything */ |
| 594 | 585 | return 1; |
| 595 | 586 | } |
| 596 | 587 | /* explicit request or no special characters? */ |
| 597 | 588 | if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { |
| 598 | 589 | /* do a plain search */ |
| 599 | const char *s2 = lmemfind(s + init - 1, ls - | |
| 590 | const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp); | |
| 600 | 591 | if (s2) { |
| 601 | 592 | lua_pushinteger(L, s2 - s + 1); |
| 602 | 593 | lua_pushinteger(L, s2 - s + lp); |
| r242899 | r242900 | |
| 687 | 678 | static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, |
| 688 | 679 | const char *e) { |
| 689 | 680 | size_t l, i; |
| 690 | lua_State *L = ms->L; | |
| 691 | const char *news = lua_tolstring(L, 3, &l); | |
| 681 | const char *news = lua_tolstring(ms->L, 3, &l); | |
| 692 | 682 | for (i = 0; i < l; i++) { |
| 693 | 683 | if (news[i] != L_ESC) |
| 694 | 684 | luaL_addchar(b, news[i]); |
| r242899 | r242900 | |
| 696 | 686 | i++; /* skip ESC */ |
| 697 | 687 | if (!isdigit(uchar(news[i]))) { |
| 698 | 688 | if (news[i] != L_ESC) |
| 699 | luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); | |
| 689 | luaL_error(ms->L, "invalid use of " LUA_QL("%c") | |
| 690 | " in replacement string", L_ESC); | |
| 700 | 691 | luaL_addchar(b, news[i]); |
| 701 | 692 | } |
| 702 | 693 | else if (news[i] == '0') |
| 703 | 694 | luaL_addlstring(b, s, e - s); |
| 704 | 695 | else { |
| 705 | 696 | push_onecapture(ms, news[i] - '1', s, e); |
| 706 | luaL_tolstring(L, -1, NULL); /* if number, convert it to string */ | |
| 707 | lua_remove(L, -2); /* remove original value */ | |
| 708 | 697 | luaL_addvalue(b); /* add capture to accumulated result */ |
| 709 | 698 | } |
| 710 | 699 | } |
| r242899 | r242900 | |
| 748 | 737 | const char *src = luaL_checklstring(L, 1, &srcl); |
| 749 | 738 | const char *p = luaL_checklstring(L, 2, &lp); |
| 750 | 739 | int tr = lua_type(L, 3); |
| 751 | | |
| 740 | size_t max_s = luaL_optinteger(L, 4, srcl+1); | |
| 752 | 741 | int anchor = (*p == '^'); |
| 753 | | |
| 742 | size_t n = 0; | |
| 754 | 743 | MatchState ms; |
| 755 | 744 | luaL_Buffer b; |
| 756 | 745 | luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || |
| r242899 | r242900 | |
| 797 | 786 | ** ======================================================= |
| 798 | 787 | */ |
| 799 | 788 | |
| 789 | /* | |
| 790 | ** LUA_INTFRMLEN is the length modifier for integer conversions in | |
| 791 | ** 'string.format'; LUA_INTFRM_T is the integer type corresponding to | |
| 792 | ** the previous length | |
| 793 | */ | |
| 794 | #if !defined(LUA_INTFRMLEN) /* { */ | |
| 795 | #if defined(LUA_USE_LONGLONG) | |
| 796 | ||
| 797 | #define LUA_INTFRMLEN "ll" | |
| 798 | #define LUA_INTFRM_T long long | |
| 799 | ||
| 800 | #else | |
| 801 | ||
| 802 | #define LUA_INTFRMLEN "l" | |
| 803 | #define LUA_INTFRM_T long | |
| 804 | ||
| 805 | #endif | |
| 806 | #endif /* } */ | |
| 807 | ||
| 808 | ||
| 809 | /* | |
| 810 | ** LUA_FLTFRMLEN is the length modifier for float conversions in | |
| 811 | ** 'string.format'; LUA_FLTFRM_T is the float type corresponding to | |
| 812 | ** the previous length | |
| 813 | */ | |
| 814 | #if !defined(LUA_FLTFRMLEN) | |
| 815 | ||
| 816 | #define LUA_FLTFRMLEN "" | |
| 817 | #define LUA_FLTFRM_T double | |
| 818 | ||
| 819 | #endif | |
| 820 | ||
| 821 | ||
| 800 | 822 | /* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ |
| 801 | 823 | #define MAX_ITEM 512 |
| 802 | ||
| 803 | 824 | /* valid flags in a format specification */ |
| 804 | 825 | #define FLAGS "-+ #0" |
| 805 | ||
| 806 | 826 | /* |
| 807 | ** maximum size of each format specification (such as "%-099.99d") | |
| 808 | ** (+2 for length modifiers; +10 accounts for %99.99x plus margin of error) | |
| 827 | ** maximum size of each format specification (such as '%-099.99d') | |
| 828 | ** (+10 accounts for %99.99x plus margin of error) | |
| 809 | 829 | */ |
| 810 | #define MAX_FORMAT (sizeof(FLAGS) + | |
| 830 | #define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) | |
| 811 | 831 | |
| 812 | 832 | |
| 813 | 833 | static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { |
| r242899 | r242900 | |
| 883 | 903 | else if (*++strfrmt == L_ESC) |
| 884 | 904 | luaL_addchar(&b, *strfrmt++); /* %% */ |
| 885 | 905 | else { /* format item */ |
| 886 | char form[MAX_FORMAT]; /* to store the format ( | |
| 906 | char form[MAX_FORMAT]; /* to store the format (`%...') */ | |
| 887 | 907 | char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ |
| 888 | 908 | int nb = 0; /* number of bytes in added item */ |
| 889 | 909 | if (++arg > top) |
| r242899 | r242900 | |
| 891 | 911 | strfrmt = scanformat(L, strfrmt, form); |
| 892 | 912 | switch (*strfrmt++) { |
| 893 | 913 | case 'c': { |
| 894 | nb = sprintf(buff, form, | |
| 914 | nb = sprintf(buff, form, luaL_checkint(L, arg)); | |
| 895 | 915 | break; |
| 896 | 916 | } |
| 897 | case 'd': case 'i': | |
| 917 | case 'd': case 'i': { | |
| 918 | lua_Number n = luaL_checknumber(L, arg); | |
| 919 | LUA_INTFRM_T ni = (LUA_INTFRM_T)n; | |
| 920 | lua_Number diff = n - (lua_Number)ni; | |
| 921 | luaL_argcheck(L, -1 < diff && diff < 1, arg, | |
| 922 | "not a number in proper range"); | |
| 923 | addlenmod(form, LUA_INTFRMLEN); | |
| 924 | nb = sprintf(buff, form, ni); | |
| 925 | break; | |
| 926 | } | |
| 898 | 927 | case 'o': case 'u': case 'x': case 'X': { |
| 899 | lua_Integer n = luaL_checkinteger(L, arg); | |
| 900 | addlenmod(form, LUA_INTEGER_FRMLEN); | |
| 901 | nb = sprintf(buff, form, n); | |
| 928 | lua_Number n = luaL_checknumber(L, arg); | |
| 929 | unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n; | |
| 930 | lua_Number diff = n - (lua_Number)ni; | |
| 931 | luaL_argcheck(L, -1 < diff && diff < 1, arg, | |
| 932 | "not a non-negative number in proper range"); | |
| 933 | addlenmod(form, LUA_INTFRMLEN); | |
| 934 | nb = sprintf(buff, form, ni); | |
| 902 | 935 | break; |
| 903 | 936 | } |
| 937 | case 'e': case 'E': case 'f': | |
| 904 | 938 | #if defined(LUA_USE_AFORMAT) |
| 905 | 939 | case 'a': case 'A': |
| 906 | 940 | #endif |
| 907 | case 'e': case 'E': case 'f': | |
| 908 | 941 | case 'g': case 'G': { |
| 909 | addlenmod(form, LUA_NUMBER_FRMLEN); | |
| 910 | nb = sprintf(buff, form, luaL_checknumber(L, arg)); | |
| 942 | addlenmod(form, LUA_FLTFRMLEN); | |
| 943 | nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); | |
| 911 | 944 | break; |
| 912 | 945 | } |
| 913 | 946 | case 'q': { |
| r242899 | r242900 | |
| 929 | 962 | break; |
| 930 | 963 | } |
| 931 | 964 | } |
| 932 | default: { /* also treat cases 'pnLlh' */ | |
| 933 | return luaL_error(L, "invalid option '%%%c' to 'format'", | |
| 934 | *(strfrmt - 1)); | |
| 965 | default: { /* also treat cases `pnLlh' */ | |
| 966 | return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " | |
| 967 | LUA_QL("format"), *(strfrmt - 1)); | |
| 935 | 968 | } |
| 936 | 969 | } |
| 937 | 970 | luaL_addsize(&b, nb); |
| r242899 | r242900 | |
| 944 | 977 | /* }====================================================== */ |
| 945 | 978 | |
| 946 | 979 | |
| 947 | /* | |
| 948 | ** {====================================================== | |
| 949 | ** PACK/UNPACK | |
| 950 | ** ======================================================= | |
| 951 | */ | |
| 952 | ||
| 953 | ||
| 954 | /* value used for padding */ | |
| 955 | #if !defined(LUA_PACKPADBYTE) | |
| 956 | #define LUA_PACKPADBYTE 0x00 | |
| 957 | #endif | |
| 958 | ||
| 959 | /* maximum size for the binary representation of an integer */ | |
| 960 | #define MAXINTSIZE 16 | |
| 961 | ||
| 962 | /* number of bits in a character */ | |
| 963 | #define NB CHAR_BIT | |
| 964 | ||
| 965 | /* mask for one character (NB 1's) */ | |
| 966 | #define MC ((1 << NB) - 1) | |
| 967 | ||
| 968 | /* size of a lua_Integer */ | |
| 969 | #define SZINT ((int)sizeof(lua_Integer)) | |
| 970 | ||
| 971 | ||
| 972 | /* dummy union to get native endianness */ | |
| 973 | static const union { | |
| 974 | int dummy; | |
| 975 | char little; /* true iff machine is little endian */ | |
| 976 | } nativeendian = {1}; | |
| 977 | ||
| 978 | ||
| 979 | /* dummy structure to get native alignment requirements */ | |
| 980 | struct cD { | |
| 981 | char c; | |
| 982 | union { double d; void *p; lua_Integer i; lua_Number n; } u; | |
| 983 | }; | |
| 984 | ||
| 985 | #define MAXALIGN (offsetof(struct cD, u)) | |
| 986 | ||
| 987 | ||
| 988 | /* | |
| 989 | ** Union for serializing floats | |
| 990 | */ | |
| 991 | typedef union Ftypes { | |
| 992 | float f; | |
| 993 | double d; | |
| 994 | lua_Number n; | |
| 995 | char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ | |
| 996 | } Ftypes; | |
| 997 | ||
| 998 | ||
| 999 | /* | |
| 1000 | ** information to pack/unpack stuff | |
| 1001 | */ | |
| 1002 | typedef struct Header { | |
| 1003 | lua_State *L; | |
| 1004 | int islittle; | |
| 1005 | int maxalign; | |
| 1006 | } Header; | |
| 1007 | ||
| 1008 | ||
| 1009 | /* | |
| 1010 | ** options for pack/unpack | |
| 1011 | */ | |
| 1012 | typedef enum KOption { | |
| 1013 | Kint, /* signed integers */ | |
| 1014 | Kuint, /* unsigned integers */ | |
| 1015 | Kfloat, /* floating-point numbers */ | |
| 1016 | Kchar, /* fixed-length strings */ | |
| 1017 | Kstring, /* strings with prefixed length */ | |
| 1018 | Kzstr, /* zero-terminated strings */ | |
| 1019 | Kpadding, /* padding */ | |
| 1020 | Kpaddalign, /* padding for alignment */ | |
| 1021 | Knop /* no-op (configuration or spaces) */ | |
| 1022 | } KOption; | |
| 1023 | ||
| 1024 | ||
| 1025 | /* | |
| 1026 | ** Read an integer numeral from string 'fmt' or return 'df' if | |
| 1027 | ** there is no numeral | |
| 1028 | */ | |
| 1029 | static int digit (int c) { return '0' <= c && c <= '9'; } | |
| 1030 | ||
| 1031 | static int getnum (const char **fmt, int df) { | |
| 1032 | if (!digit(**fmt)) /* no number? */ | |
| 1033 | return df; /* return default value */ | |
| 1034 | else { | |
| 1035 | int a = 0; | |
| 1036 | do { | |
| 1037 | a = a*10 + (*((*fmt)++) - '0'); | |
| 1038 | } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); | |
| 1039 | return a; | |
| 1040 | } | |
| 1041 | } | |
| 1042 | ||
| 1043 | ||
| 1044 | /* | |
| 1045 | ** Read an integer numeral and raises an error if it is larger | |
| 1046 | ** than the maximum size for integers. | |
| 1047 | */ | |
| 1048 | static int getnumlimit (Header *h, const char **fmt, int df) { | |
| 1049 | int sz = getnum(fmt, df); | |
| 1050 | if (sz > MAXINTSIZE || sz <= 0) | |
| 1051 | luaL_error(h->L, "integral size (%d) out of limits [1,%d]", | |
| 1052 | sz, MAXINTSIZE); | |
| 1053 | return sz; | |
| 1054 | } | |
| 1055 | ||
| 1056 | ||
| 1057 | /* | |
| 1058 | ** Initialize Header | |
| 1059 | */ | |
| 1060 | static void initheader (lua_State *L, Header *h) { | |
| 1061 | h->L = L; | |
| 1062 | h->islittle = nativeendian.little; | |
| 1063 | h->maxalign = 1; | |
| 1064 | } | |
| 1065 | ||
| 1066 | ||
| 1067 | /* | |
| 1068 | ** Read and classify next option. 'size' is filled with option's size. | |
| 1069 | */ | |
| 1070 | static KOption getoption (Header *h, const char **fmt, int *size) { | |
| 1071 | int opt = *((*fmt)++); | |
| 1072 | *size = 0; /* default */ | |
| 1073 | switch (opt) { | |
| 1074 | case 'b': *size = sizeof(char); return Kint; | |
| 1075 | case 'B': *size = sizeof(char); return Kuint; | |
| 1076 | case 'h': *size = sizeof(short); return Kint; | |
| 1077 | case 'H': *size = sizeof(short); return Kuint; | |
| 1078 | case 'l': *size = sizeof(long); return Kint; | |
| 1079 | case 'L': *size = sizeof(long); return Kuint; | |
| 1080 | case 'j': *size = sizeof(lua_Integer); return Kint; | |
| 1081 | case 'J': *size = sizeof(lua_Integer); return Kuint; | |
| 1082 | case 'T': *size = sizeof(size_t); return Kuint; | |
| 1083 | case 'f': *size = sizeof(float); return Kfloat; | |
| 1084 | case 'd': *size = sizeof(double); return Kfloat; | |
| 1085 | case 'n': *size = sizeof(lua_Number); return Kfloat; | |
| 1086 | case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; | |
| 1087 | case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; | |
| 1088 | case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; | |
| 1089 | case 'c': | |
| 1090 | *size = getnum(fmt, -1); | |
| 1091 | if (*size == -1) | |
| 1092 | luaL_error(h->L, "missing size for format option 'c'"); | |
| 1093 | return Kchar; | |
| 1094 | case 'z': return Kzstr; | |
| 1095 | case 'x': *size = 1; return Kpadding; | |
| 1096 | case 'X': return Kpaddalign; | |
| 1097 | case ' ': break; | |
| 1098 | case '<': h->islittle = 1; break; | |
| 1099 | case '>': h->islittle = 0; break; | |
| 1100 | case '=': h->islittle = nativeendian.little; break; | |
| 1101 | case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break; | |
| 1102 | default: luaL_error(h->L, "invalid format option '%c'", opt); | |
| 1103 | } | |
| 1104 | return Knop; | |
| 1105 | } | |
| 1106 | ||
| 1107 | ||
| 1108 | /* | |
| 1109 | ** Read, classify, and fill other details about the next option. | |
| 1110 | ** 'psize' is filled with option's size, 'notoalign' with its | |
| 1111 | ** alignment requirements. | |
| 1112 | ** Local variable 'size' gets the size to be aligned. (Kpadal option | |
| 1113 | ** always gets its full alignment, other options are limited by | |
| 1114 | ** the maximum alignment ('maxalign'). Kchar option needs no alignment | |
| 1115 | ** despite its size. | |
| 1116 | */ | |
| 1117 | static KOption getdetails (Header *h, size_t totalsize, | |
| 1118 | const char **fmt, int *psize, int *ntoalign) { | |
| 1119 | KOption opt = getoption(h, fmt, psize); | |
| 1120 | int align = *psize; /* usually, alignment follows size */ | |
| 1121 | if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ | |
| 1122 | if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) | |
| 1123 | luaL_argerror(h->L, 1, "invalid next option for option 'X'"); | |
| 1124 | } | |
| 1125 | if (align <= 1 || opt == Kchar) /* need no alignment? */ | |
| 1126 | *ntoalign = 0; | |
| 1127 | else { | |
| 1128 | if (align > h->maxalign) /* enforce maximum alignment */ | |
| 1129 | align = h->maxalign; | |
| 1130 | if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ | |
| 1131 | luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); | |
| 1132 | *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); | |
| 1133 | } | |
| 1134 | return opt; | |
| 1135 | } | |
| 1136 | ||
| 1137 | ||
| 1138 | /* | |
| 1139 | ** Pack integer 'n' with 'size' bytes and 'islittle' endianness. | |
| 1140 | ** The final 'if' handles the case when 'size' is larger than | |
| 1141 | ** the size of a Lua integer, correcting the extra sign-extension | |
| 1142 | ** bytes if necessary (by default they would be zeros). | |
| 1143 | */ | |
| 1144 | static void packint (luaL_Buffer *b, lua_Unsigned n, | |
| 1145 | int islittle, int size, int neg) { | |
| 1146 | char *buff = luaL_prepbuffsize(b, size); | |
| 1147 | int i; | |
| 1148 | buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ | |
| 1149 | for (i = 1; i < size; i++) { | |
| 1150 | n >>= NB; | |
| 1151 | buff[islittle ? i : size - 1 - i] = (char)(n & MC); | |
| 1152 | } | |
| 1153 | if (neg && size > SZINT) { /* negative number need sign extension? */ | |
| 1154 | for (i = SZINT; i < size; i++) /* correct extra bytes */ | |
| 1155 | buff[islittle ? i : size - 1 - i] = (char)MC; | |
| 1156 | } | |
| 1157 | luaL_addsize(b, size); /* add result to buffer */ | |
| 1158 | } | |
| 1159 | ||
| 1160 | ||
| 1161 | /* | |
| 1162 | ** Copy 'size' bytes from 'src' to 'dest', correcting endianness if | |
| 1163 | ** given 'islittle' is different from native endianness. | |
| 1164 | */ | |
| 1165 | static void copywithendian (volatile char *dest, volatile const char *src, | |
| 1166 | int size, int islittle) { | |
| 1167 | if (islittle == nativeendian.little) { | |
| 1168 | while (size-- != 0) | |
| 1169 | *(dest++) = *(src++); | |
| 1170 | } | |
| 1171 | else { | |
| 1172 | dest += size - 1; | |
| 1173 | while (size-- != 0) | |
| 1174 | *(dest--) = *(src++); | |
| 1175 | } | |
| 1176 | } | |
| 1177 | ||
| 1178 | ||
| 1179 | static int str_pack (lua_State *L) { | |
| 1180 | luaL_Buffer b; | |
| 1181 | Header h; | |
| 1182 | const char *fmt = luaL_checkstring(L, 1); /* format string */ | |
| 1183 | int arg = 1; /* current argument to pack */ | |
| 1184 | size_t totalsize = 0; /* accumulate total size of result */ | |
| 1185 | initheader(L, &h); | |
| 1186 | lua_pushnil(L); /* mark to separate arguments from string buffer */ | |
| 1187 | luaL_buffinit(L, &b); | |
| 1188 | while (*fmt != '\0') { | |
| 1189 | int size, ntoalign; | |
| 1190 | KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); | |
| 1191 | totalsize += ntoalign + size; | |
| 1192 | while (ntoalign-- > 0) | |
| 1193 | luaL_addchar(&b, LUA_PACKPADBYTE); /* fill alignment */ | |
| 1194 | arg++; | |
| 1195 | switch (opt) { | |
| 1196 | case Kint: { /* signed integers */ | |
| 1197 | lua_Integer n = luaL_checkinteger(L, arg); | |
| 1198 | if (size < SZINT) { /* need overflow check? */ | |
| 1199 | lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); | |
| 1200 | luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); | |
| 1201 | } | |
| 1202 | packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); | |
| 1203 | break; | |
| 1204 | } | |
| 1205 | case Kuint: { /* unsigned integers */ | |
| 1206 | lua_Integer n = luaL_checkinteger(L, arg); | |
| 1207 | if (size < SZINT) /* need overflow check? */ | |
| 1208 | luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), | |
| 1209 | arg, "unsigned overflow"); | |
| 1210 | packint(&b, (lua_Unsigned)n, h.islittle, size, 0); | |
| 1211 | break; | |
| 1212 | } | |
| 1213 | case Kfloat: { /* floating-point options */ | |
| 1214 | volatile Ftypes u; | |
| 1215 | char *buff = luaL_prepbuffsize(&b, size); | |
| 1216 | lua_Number n = luaL_checknumber(L, arg); /* get argument */ | |
| 1217 | if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ | |
| 1218 | else if (size == sizeof(u.d)) u.d = (double)n; | |
| 1219 | else u.n = n; | |
| 1220 | /* move 'u' to final result, correcting endianness if needed */ | |
| 1221 | copywithendian(buff, u.buff, size, h.islittle); | |
| 1222 | luaL_addsize(&b, size); | |
| 1223 | break; | |
| 1224 | } | |
| 1225 | case Kchar: { /* fixed-size string */ | |
| 1226 | size_t len; | |
| 1227 | const char *s = luaL_checklstring(L, arg, &len); | |
| 1228 | luaL_argcheck(L, len == (size_t)size, arg, "wrong length"); | |
| 1229 | luaL_addlstring(&b, s, size); | |
| 1230 | break; | |
| 1231 | } | |
| 1232 | case Kstring: { /* strings with length count */ | |
| 1233 | size_t len; | |
| 1234 | const char *s = luaL_checklstring(L, arg, &len); | |
| 1235 | luaL_argcheck(L, size >= (int)sizeof(size_t) || | |
| 1236 | len < ((size_t)1 << (size * NB)), | |
| 1237 | arg, "string length does not fit in given size"); | |
| 1238 | packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ | |
| 1239 | luaL_addlstring(&b, s, len); | |
| 1240 | totalsize += len; | |
| 1241 | break; | |
| 1242 | } | |
| 1243 | case Kzstr: { /* zero-terminated string */ | |
| 1244 | size_t len; | |
| 1245 | const char *s = luaL_checklstring(L, arg, &len); | |
| 1246 | luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); | |
| 1247 | luaL_addlstring(&b, s, len); | |
| 1248 | luaL_addchar(&b, '\0'); /* add zero at the end */ | |
| 1249 | totalsize += len + 1; | |
| 1250 | break; | |
| 1251 | } | |
| 1252 | case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* go through */ | |
| 1253 | case Kpaddalign: case Knop: | |
| 1254 | arg--; /* undo increment */ | |
| 1255 | break; | |
| 1256 | } | |
| 1257 | } | |
| 1258 | luaL_pushresult(&b); | |
| 1259 | return 1; | |
| 1260 | } | |
| 1261 | ||
| 1262 | ||
| 1263 | static int str_packsize (lua_State *L) { | |
| 1264 | Header h; | |
| 1265 | const char *fmt = luaL_checkstring(L, 1); /* format string */ | |
| 1266 | size_t totalsize = 0; /* accumulate total size of result */ | |
| 1267 | initheader(L, &h); | |
| 1268 | while (*fmt != '\0') { | |
| 1269 | int size, ntoalign; | |
| 1270 | KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); | |
| 1271 | size += ntoalign; /* total space used by option */ | |
| 1272 | luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, | |
| 1273 | "format result too large"); | |
| 1274 | totalsize += size; | |
| 1275 | switch (opt) { | |
| 1276 | case Kstring: /* strings with length count */ | |
| 1277 | case Kzstr: /* zero-terminated string */ | |
| 1278 | luaL_argerror(L, 1, "variable-length format"); | |
| 1279 | break; | |
| 1280 | default: break; | |
| 1281 | } | |
| 1282 | } | |
| 1283 | lua_pushinteger(L, (lua_Integer)totalsize); | |
| 1284 | return 1; | |
| 1285 | } | |
| 1286 | ||
| 1287 | ||
| 1288 | /* | |
| 1289 | ** Unpack an integer with 'size' bytes and 'islittle' endianness. | |
| 1290 | ** If size is smaller than the size of a Lua integer and integer | |
| 1291 | ** is signed, must do sign extension (propagating the sign to the | |
| 1292 | ** higher bits); if size is larger than the size of a Lua integer, | |
| 1293 | ** it must check the unread bytes to see whether they do not cause an | |
| 1294 | ** overflow. | |
| 1295 | */ | |
| 1296 | static lua_Integer unpackint (lua_State *L, const char *str, | |
| 1297 | int islittle, int size, int issigned) { | |
| 1298 | lua_Unsigned res = 0; | |
| 1299 | int i; | |
| 1300 | int limit = (size <= SZINT) ? size : SZINT; | |
| 1301 | for (i = limit - 1; i >= 0; i--) { | |
| 1302 | res <<= NB; | |
| 1303 | res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; | |
| 1304 | } | |
| 1305 | if (size < SZINT) { /* real size smaller than lua_Integer? */ | |
| 1306 | if (issigned) { /* needs sign extension? */ | |
| 1307 | lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); | |
| 1308 | res = ((res ^ mask) - mask); /* do sign extension */ | |
| 1309 | } | |
| 1310 | } | |
| 1311 | else if (size > SZINT) { /* must check unread bytes */ | |
| 1312 | int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; | |
| 1313 | for (i = limit; i < size; i++) { | |
| 1314 | if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) | |
| 1315 | luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); | |
| 1316 | } | |
| 1317 | } | |
| 1318 | return (lua_Integer)res; | |
| 1319 | } | |
| 1320 | ||
| 1321 | ||
| 1322 | static int str_unpack (lua_State *L) { | |
| 1323 | Header h; | |
| 1324 | const char *fmt = luaL_checkstring(L, 1); | |
| 1325 | size_t ld; | |
| 1326 | const char *data = luaL_checklstring(L, 2, &ld); | |
| 1327 | size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; | |
| 1328 | int n = 0; /* number of results */ | |
| 1329 | luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); | |
| 1330 | initheader(L, &h); | |
| 1331 | while (*fmt != '\0') { | |
| 1332 | int size, ntoalign; | |
| 1333 | KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); | |
| 1334 | if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) | |
| 1335 | luaL_argerror(L, 2, "data string too short"); | |
| 1336 | pos += ntoalign; /* skip alignment */ | |
| 1337 | /* stack space for item + next position */ | |
| 1338 | luaL_checkstack(L, 2, "too many results"); | |
| 1339 | n++; | |
| 1340 | switch (opt) { | |
| 1341 | case Kint: | |
| 1342 | case Kuint: { | |
| 1343 | lua_Integer res = unpackint(L, data + pos, h.islittle, size, | |
| 1344 | (opt == Kint)); | |
| 1345 | lua_pushinteger(L, res); | |
| 1346 | break; | |
| 1347 | } | |
| 1348 | case Kfloat: { | |
| 1349 | volatile Ftypes u; | |
| 1350 | lua_Number num; | |
| 1351 | copywithendian(u.buff, data + pos, size, h.islittle); | |
| 1352 | if (size == sizeof(u.f)) num = (lua_Number)u.f; | |
| 1353 | else if (size == sizeof(u.d)) num = (lua_Number)u.d; | |
| 1354 | else num = u.n; | |
| 1355 | lua_pushnumber(L, num); | |
| 1356 | break; | |
| 1357 | } | |
| 1358 | case Kchar: { | |
| 1359 | lua_pushlstring(L, data + pos, size); | |
| 1360 | break; | |
| 1361 | } | |
| 1362 | case Kstring: { | |
| 1363 | size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); | |
| 1364 | luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); | |
| 1365 | lua_pushlstring(L, data + pos + size, len); | |
| 1366 | pos += len; /* skip string */ | |
| 1367 | break; | |
| 1368 | } | |
| 1369 | case Kzstr: { | |
| 1370 | size_t len = (int)strlen(data + pos); | |
| 1371 | lua_pushlstring(L, data + pos, len); | |
| 1372 | pos += len + 1; /* skip string plus final '\0' */ | |
| 1373 | break; | |
| 1374 | } | |
| 1375 | case Kpaddalign: case Kpadding: case Knop: | |
| 1376 | n--; /* undo increment */ | |
| 1377 | break; | |
| 1378 | } | |
| 1379 | pos += size; | |
| 1380 | } | |
| 1381 | lua_pushinteger(L, pos + 1); /* next position */ | |
| 1382 | return n + 1; | |
| 1383 | } | |
| 1384 | ||
| 1385 | /* }====================================================== */ | |
| 1386 | ||
| 1387 | ||
| 1388 | 980 | static const luaL_Reg strlib[] = { |
| 1389 | 981 | {"byte", str_byte}, |
| 1390 | 982 | {"char", str_char}, |
| r242899 | r242900 | |
| 1400 | 992 | {"reverse", str_reverse}, |
| 1401 | 993 | {"sub", str_sub}, |
| 1402 | 994 | {"upper", str_upper}, |
| 1403 | {"pack", str_pack}, | |
| 1404 | {"packsize", str_packsize}, | |
| 1405 | {"unpack", str_unpack}, | |
| 1406 | 995 | {NULL, NULL} |
| 1407 | 996 | }; |
| 1408 | 997 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.1 | |
| 2 | ** $Id: ltable.c,v 2.72.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lua tables (hash) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define ltable_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | /* |
| 14 | 9 | ** Implementation of tables (aka arrays, objects, or hash tables). |
| 15 | 10 | ** Tables keep its elements in two parts: an array part and a hash part. |
| 16 | 11 | ** Non-negative integer keys are all candidates to be kept in the array |
| 17 | ** part. The actual size of the array is the largest | |
| 12 | ** part. The actual size of the array is the largest `n' such that at | |
| 18 | 13 | ** least half the slots between 0 and n are in use. |
| 19 | 14 | ** Hash uses a mix of chained scatter table with Brent's variation. |
| 20 | 15 | ** A main invariant of these tables is that, if an element is not |
| 21 | ** in its main position (i.e. the | |
| 16 | ** in its main position (i.e. the `original' position that its hash gives | |
| 22 | 17 | ** to it), then the colliding element is in its own main position. |
| 23 | 18 | ** Hence even when the load factor reaches 100%, performance remains good. |
| 24 | 19 | */ |
| 25 | 20 | |
| 26 | #include <float.h> | |
| 27 | #include <math.h> | |
| 28 | 21 | #include <string.h> |
| 29 | #include <limits.h> | |
| 30 | 22 | |
| 23 | #define ltable_c | |
| 24 | #define LUA_CORE | |
| 25 | ||
| 31 | 26 | #include "lua.h" |
| 32 | 27 | |
| 33 | 28 | #include "ldebug.h" |
| r242899 | r242900 | |
| 42 | 37 | |
| 43 | 38 | |
| 44 | 39 | /* |
| 45 | ** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is | |
| 46 | ** the largest integer such that MAXASIZE fits in an unsigned int. | |
| 40 | ** max size of array part is 2^MAXBITS | |
| 47 | 41 | */ |
| 48 | #define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) | |
| 49 | #define MAXASIZE (1u << MAXABITS) | |
| 42 | #if LUAI_BITSINT >= 32 | |
| 43 | #define MAXBITS 30 | |
| 44 | #else | |
| 45 | #define MAXBITS (LUAI_BITSINT-2) | |
| 46 | #endif | |
| 50 | 47 | |
| 51 | /* | |
| 52 | ** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest | |
| 53 | ** integer such that 2^MAXHBITS fits in a signed int. (Note that the | |
| 54 | ** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still | |
| 55 | ** fits comfortably in an unsigned int.) | |
| 56 | */ | |
| 57 | #define MAXHBITS (MAXABITS - 1) | |
| 48 | #define MAXASIZE (1 << MAXBITS) | |
| 58 | 49 | |
| 59 | 50 | |
| 60 | 51 | #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) |
| 61 | 52 | |
| 62 | #define hashstr(t,str) hashpow2(t, (str)->hash) | |
| 53 | #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) | |
| 63 | 54 | #define hashboolean(t,p) hashpow2(t, p) |
| 64 | #define hashint(t,i) hashpow2(t, i) | |
| 65 | 55 | |
| 66 | 56 | |
| 67 | 57 | /* |
| r242899 | r242900 | |
| 71 | 61 | #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) |
| 72 | 62 | |
| 73 | 63 | |
| 74 | #define hashpointer(t,p) hashmod(t, | |
| 64 | #define hashpointer(t,p) hashmod(t, IntPoint(p)) | |
| 75 | 65 | |
| 76 | 66 | |
| 77 | 67 | #define dummynode (&dummynode_) |
| r242899 | r242900 | |
| 80 | 70 | |
| 81 | 71 | static const Node dummynode_ = { |
| 82 | 72 | {NILCONSTANT}, /* value */ |
| 83 | {{NILCONSTANT, | |
| 73 | {{NILCONSTANT, NULL}} /* key */ | |
| 84 | 74 | }; |
| 85 | 75 | |
| 86 | 76 | |
| 87 | 77 | /* |
| 88 | ** Checks whether a float has a value representable as a lua_Integer | |
| 89 | ** (and does the conversion if so) | |
| 78 | ** hash for lua_Numbers | |
| 90 | 79 | */ |
| 91 | static int numisinteger (lua_Number x, lua_Integer *p) { | |
| 92 | if ((x) == l_floor(x)) /* integral value? */ | |
| 93 | return lua_numbertointeger(x, p); /* try as an integer */ | |
| 94 | else return 0; | |
| 95 | } | |
| 96 | ||
| 97 | ||
| 98 | /* | |
| 99 | ** hash for floating-point numbers | |
| 100 | */ | |
| 101 | static Node *hashfloat (const Table *t, lua_Number n) { | |
| 80 | static Node *hashnum (const Table *t, lua_Number n) { | |
| 102 | 81 | int i; |
| 103 | n = l_mathop(frexp)(n, &i) * cast_num(INT_MAX - DBL_MAX_EXP); | |
| 104 | i += cast_int(n); | |
| 82 | luai_hashnum(i, n); | |
| 105 | 83 | if (i < 0) { |
| 106 | 84 | if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */ |
| 107 | 85 | i = 0; /* handle INT_MIN */ |
| r242899 | r242900 | |
| 113 | 91 | |
| 114 | 92 | |
| 115 | 93 | /* |
| 116 | ** returns the | |
| 94 | ** returns the `main' position of an element in a table (that is, the index | |
| 117 | 95 | ** of its hash value) |
| 118 | 96 | */ |
| 119 | 97 | static Node *mainposition (const Table *t, const TValue *key) { |
| 120 | 98 | switch (ttype(key)) { |
| 121 | case LUA_TNUMINT: | |
| 122 | return hashint(t, ivalue(key)); | |
| 123 | case LUA_TNUMFLT: | |
| 124 | return hashfloat(t, fltvalue(key)); | |
| 125 | case LUA_TSHRSTR: | |
| 126 | return hashstr(t, tsvalue(key)); | |
| 99 | case LUA_TNUMBER: | |
| 100 | return hashnum(t, nvalue(key)); | |
| 127 | 101 | case LUA_TLNGSTR: { |
| 128 | TString *s = tsvalue(key); | |
| 129 | if (s->extra == 0) { /* no hash? */ | |
| 130 | s->hash = luaS_hash(getstr(s), s->len, s->hash); | |
| 131 | s->extra = 1; /* now it has its hash */ | |
| 102 | TString *s = rawtsvalue(key); | |
| 103 | if (s->tsv.extra == 0) { /* no hash? */ | |
| 104 | s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); | |
| 105 | s->tsv.extra = 1; /* now it has its hash */ | |
| 132 | 106 | } |
| 133 | return hashstr(t, tsvalue(key)); | |
| 107 | return hashstr(t, rawtsvalue(key)); | |
| 134 | 108 | } |
| 109 | case LUA_TSHRSTR: | |
| 110 | return hashstr(t, rawtsvalue(key)); | |
| 135 | 111 | case LUA_TBOOLEAN: |
| 136 | 112 | return hashboolean(t, bvalue(key)); |
| 137 | 113 | case LUA_TLIGHTUSERDATA: |
| r242899 | r242900 | |
| 145 | 121 | |
| 146 | 122 | |
| 147 | 123 | /* |
| 148 | ** returns the index for 'key' if 'key' is an appropriate key to live in | |
| 149 | ** the array part of the table, 0 otherwise. | |
| 124 | ** returns the index for `key' if `key' is an appropriate key to live in | |
| 125 | ** the array part of the table, -1 otherwise. | |
| 150 | 126 | */ |
| 151 | static unsigned int arrayindex (const TValue *key) { | |
| 152 | if (ttisinteger(key)) { | |
| 153 | lua_Integer k = ivalue(key); | |
| 154 | if (0 < k && (lua_Unsigned)k <= MAXASIZE) | |
| 155 | return cast(unsigned int, k); /* 'key' is an appropriate array index */ | |
| 127 | static int arrayindex (const TValue *key) { | |
| 128 | if (ttisnumber(key)) { | |
| 129 | lua_Number n = nvalue(key); | |
| 130 | int k; | |
| 131 | lua_number2int(k, n); | |
| 132 | if (luai_numeq(cast_num(k), n)) | |
| 133 | return k; | |
| 156 | 134 | } |
| 157 | return | |
| 135 | return -1; /* `key' did not match some condition */ | |
| 158 | 136 | } |
| 159 | 137 | |
| 160 | 138 | |
| 161 | 139 | /* |
| 162 | ** returns the index of a | |
| 140 | ** returns the index of a `key' for table traversals. First goes all | |
| 163 | 141 | ** elements in the array part, then elements in the hash part. The |
| 164 | ** beginning of a traversal is signaled by | |
| 142 | ** beginning of a traversal is signaled by -1. | |
| 165 | 143 | */ |
| 166 | static unsigned int findindex (lua_State *L, Table *t, StkId key) { | |
| 167 | unsigned int i; | |
| 168 | if (ttisnil(key)) return 0; /* first iteration */ | |
| 144 | static int findindex (lua_State *L, Table *t, StkId key) { | |
| 145 | int i; | |
| 146 | if (ttisnil(key)) return -1; /* first iteration */ | |
| 169 | 147 | i = arrayindex(key); |
| 170 | if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */ | |
| 171 | return i; /* yes; that's the index */ | |
| 148 | if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ | |
| 149 | return i-1; /* yes; that's the index (corrected to C) */ | |
| 172 | 150 | else { |
| 173 | int nx; | |
| 174 | 151 | Node *n = mainposition(t, key); |
| 175 | for (;;) { /* check whether 'key' is somewhere in the chain */ | |
| 176 | /* key may be dead already, but it is ok to use it in 'next' */ | |
| 152 | for (;;) { /* check whether `key' is somewhere in the chain */ | |
| 153 | /* key may be dead already, but it is ok to use it in `next' */ | |
| 177 | 154 | if (luaV_rawequalobj(gkey(n), key) || |
| 178 | 155 | (ttisdeadkey(gkey(n)) && iscollectable(key) && |
| 179 | 156 | deadvalue(gkey(n)) == gcvalue(key))) { |
| 180 | 157 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ |
| 181 | 158 | /* hash elements are numbered after array ones */ |
| 182 | return | |
| 159 | return i + t->sizearray; | |
| 183 | 160 | } |
| 184 | nx = gnext(n); | |
| 185 | if (nx == 0) | |
| 186 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ | |
| 187 | else n += nx; | |
| 161 | else n = gnext(n); | |
| 162 | if (n == NULL) | |
| 163 | luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ | |
| 188 | 164 | } |
| 189 | 165 | } |
| 190 | 166 | } |
| 191 | 167 | |
| 192 | 168 | |
| 193 | 169 | int luaH_next (lua_State *L, Table *t, StkId key) { |
| 194 | unsigned int i = findindex(L, t, key); /* find original element */ | |
| 195 | for (; i < t->sizearray; i++) { /* try first array part */ | |
| 170 | int i = findindex(L, t, key); /* find original element */ | |
| 171 | for (i++; i < t->sizearray; i++) { /* try first array part */ | |
| 196 | 172 | if (!ttisnil(&t->array[i])) { /* a non-nil value? */ |
| 197 | set | |
| 173 | setnvalue(key, cast_num(i+1)); | |
| 198 | 174 | setobj2s(L, key+1, &t->array[i]); |
| 199 | 175 | return 1; |
| 200 | 176 | } |
| 201 | 177 | } |
| 202 | for (i -= t->sizearray; | |
| 178 | for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ | |
| 203 | 179 | if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ |
| 204 | 180 | setobj2s(L, key, gkey(gnode(t, i))); |
| 205 | 181 | setobj2s(L, key+1, gval(gnode(t, i))); |
| r242899 | r242900 | |
| 216 | 192 | ** ============================================================== |
| 217 | 193 | */ |
| 218 | 194 | |
| 219 | /* | |
| 220 | ** Compute the optimal size for the array part of table 't'. 'nums' is a | |
| 221 | ** "count array" where 'nums[i]' is the number of integers in the table | |
| 222 | ** between 2^(i - 1) + 1 and 2^i. Put in '*narray' the optimal size, and | |
| 223 | ** return the number of elements that will go to that part. | |
| 224 | */ | |
| 225 | static unsigned int computesizes (unsigned int nums[], unsigned int *narray) { | |
| 195 | ||
| 196 | static int computesizes (int nums[], int *narray) { | |
| 226 | 197 | int i; |
| 227 | unsigned int twotoi; /* 2^i */ | |
| 228 | unsigned int a = 0; /* number of elements smaller than 2^i */ | |
| 229 | unsigned int na = 0; /* number of elements to go to array part */ | |
| 230 | unsigned int n = 0; /* optimal size for array part */ | |
| 198 | int twotoi; /* 2^i */ | |
| 199 | int a = 0; /* number of elements smaller than 2^i */ | |
| 200 | int na = 0; /* number of elements to go to array part */ | |
| 201 | int n = 0; /* optimal size for array part */ | |
| 231 | 202 | for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { |
| 232 | 203 | if (nums[i] > 0) { |
| 233 | 204 | a += nums[i]; |
| 234 | 205 | if (a > twotoi/2) { /* more than half elements present? */ |
| 235 | 206 | n = twotoi; /* optimal size (till now) */ |
| 236 | na = a; /* all elements | |
| 207 | na = a; /* all elements smaller than n will go to array part */ | |
| 237 | 208 | } |
| 238 | 209 | } |
| 239 | 210 | if (a == *narray) break; /* all elements already counted */ |
| r242899 | r242900 | |
| 244 | 215 | } |
| 245 | 216 | |
| 246 | 217 | |
| 247 | static int countint (const TValue *key, unsigned int *nums) { | |
| 248 | unsigned int k = arrayindex(key); | |
| 249 | if (k != 0) { /* is 'key' an appropriate array index? */ | |
| 218 | static int countint (const TValue *key, int *nums) { | |
| 219 | int k = arrayindex(key); | |
| 220 | if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ | |
| 250 | 221 | nums[luaO_ceillog2(k)]++; /* count as such */ |
| 251 | 222 | return 1; |
| 252 | 223 | } |
| r242899 | r242900 | |
| 255 | 226 | } |
| 256 | 227 | |
| 257 | 228 | |
| 258 | static | |
| 229 | static int numusearray (const Table *t, int *nums) { | |
| 259 | 230 | int lg; |
| 260 | unsigned int ttlg; /* 2^lg */ | |
| 261 | unsigned int ause = 0; /* summation of 'nums' */ | |
| 262 | unsigned int i = 1; /* count to traverse all array keys */ | |
| 263 | /* traverse each slice */ | |
| 264 | for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { | |
| 265 | unsigned int lc = 0; /* counter */ | |
| 266 | unsigned int lim = ttlg; | |
| 231 | int ttlg; /* 2^lg */ | |
| 232 | int ause = 0; /* summation of `nums' */ | |
| 233 | int i = 1; /* count to traverse all array keys */ | |
| 234 | for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ | |
| 235 | int lc = 0; /* counter */ | |
| 236 | int lim = ttlg; | |
| 267 | 237 | if (lim > t->sizearray) { |
| 268 | 238 | lim = t->sizearray; /* adjust upper limit */ |
| 269 | 239 | if (i > lim) |
| 270 | 240 | break; /* no more elements to count */ |
| 271 | 241 | } |
| 272 | /* count elements in range (2^(lg | |
| 242 | /* count elements in range (2^(lg-1), 2^lg] */ | |
| 273 | 243 | for (; i <= lim; i++) { |
| 274 | 244 | if (!ttisnil(&t->array[i-1])) |
| 275 | 245 | lc++; |
| r242899 | r242900 | |
| 281 | 251 | } |
| 282 | 252 | |
| 283 | 253 | |
| 284 | static int numusehash (const Table *t, unsigned int *nums, | |
| 285 | unsigned int *pnasize) { | |
| 254 | static int numusehash (const Table *t, int *nums, int *pnasize) { | |
| 286 | 255 | int totaluse = 0; /* total number of elements */ |
| 287 | int ause = 0; /* | |
| 256 | int ause = 0; /* summation of `nums' */ | |
| 288 | 257 | int i = sizenode(t); |
| 289 | 258 | while (i--) { |
| 290 | 259 | Node *n = &t->node[i]; |
| r242899 | r242900 | |
| 298 | 267 | } |
| 299 | 268 | |
| 300 | 269 | |
| 301 | static void setarrayvector (lua_State *L, Table *t, unsigned int size) { | |
| 302 | unsigned int i; | |
| 270 | static void setarrayvector (lua_State *L, Table *t, int size) { | |
| 271 | int i; | |
| 303 | 272 | luaM_reallocvector(L, t->array, t->sizearray, size, TValue); |
| 304 | 273 | for (i=t->sizearray; i<size; i++) |
| 305 | 274 | setnilvalue(&t->array[i]); |
| r242899 | r242900 | |
| 307 | 276 | } |
| 308 | 277 | |
| 309 | 278 | |
| 310 | static void setnodevector (lua_State *L, Table *t, | |
| 279 | static void setnodevector (lua_State *L, Table *t, int size) { | |
| 311 | 280 | int lsize; |
| 312 | 281 | if (size == 0) { /* no elements to hash part? */ |
| 313 | t->node = cast(Node *, dummynode); /* use common | |
| 282 | t->node = cast(Node *, dummynode); /* use common `dummynode' */ | |
| 314 | 283 | lsize = 0; |
| 315 | 284 | } |
| 316 | 285 | else { |
| 317 | 286 | int i; |
| 318 | 287 | lsize = luaO_ceillog2(size); |
| 319 | if (lsize > MAX | |
| 288 | if (lsize > MAXBITS) | |
| 320 | 289 | luaG_runerror(L, "table overflow"); |
| 321 | 290 | size = twoto(lsize); |
| 322 | 291 | t->node = luaM_newvector(L, size, Node); |
| 323 | for (i | |
| 292 | for (i=0; i<size; i++) { | |
| 324 | 293 | Node *n = gnode(t, i); |
| 325 | gnext(n) = 0; | |
| 326 | setnilvalue(wgkey(n)); | |
| 294 | gnext(n) = NULL; | |
| 295 | setnilvalue(gkey(n)); | |
| 327 | 296 | setnilvalue(gval(n)); |
| 328 | 297 | } |
| 329 | 298 | } |
| r242899 | r242900 | |
| 332 | 301 | } |
| 333 | 302 | |
| 334 | 303 | |
| 335 | void luaH_resize (lua_State *L, Table *t, unsigned int nasize, | |
| 336 | unsigned int nhsize) { | |
| 337 | unsigned int i; | |
| 338 | int j; | |
| 339 | unsigned int oldasize = t->sizearray; | |
| 304 | void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { | |
| 305 | int i; | |
| 306 | int oldasize = t->sizearray; | |
| 340 | 307 | int oldhsize = t->lsizenode; |
| 341 | 308 | Node *nold = t->node; /* save old hash ... */ |
| 342 | 309 | if (nasize > oldasize) /* array part must grow? */ |
| r242899 | r242900 | |
| 354 | 321 | luaM_reallocvector(L, t->array, oldasize, nasize, TValue); |
| 355 | 322 | } |
| 356 | 323 | /* re-insert elements from hash part */ |
| 357 | for (j = twoto(oldhsize) - 1; j >= 0; j--) { | |
| 358 | Node *old = nold + j; | |
| 324 | for (i = twoto(oldhsize) - 1; i >= 0; i--) { | |
| 325 | Node *old = nold+i; | |
| 359 | 326 | if (!ttisnil(gval(old))) { |
| 360 | 327 | /* doesn't need barrier/invalidate cache, as entry was |
| 361 | 328 | already present in the table */ |
| r242899 | r242900 | |
| 367 | 334 | } |
| 368 | 335 | |
| 369 | 336 | |
| 370 | void luaH_resizearray (lua_State *L, Table *t, | |
| 337 | void luaH_resizearray (lua_State *L, Table *t, int nasize) { | |
| 371 | 338 | int nsize = isdummy(t->node) ? 0 : sizenode(t); |
| 372 | 339 | luaH_resize(L, t, nasize, nsize); |
| 373 | 340 | } |
| 374 | 341 | |
| 375 | /* | |
| 376 | ** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i | |
| 377 | */ | |
| 342 | ||
| 378 | 343 | static void rehash (lua_State *L, Table *t, const TValue *ek) { |
| 379 | unsigned int nasize, na; | |
| 380 | unsigned int nums[MAXABITS + 1]; | |
| 344 | int nasize, na; | |
| 345 | int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ | |
| 381 | 346 | int i; |
| 382 | 347 | int totaluse; |
| 383 | for (i | |
| 348 | for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ | |
| 384 | 349 | nasize = numusearray(t, nums); /* count keys in array part */ |
| 385 | 350 | totaluse = nasize; /* all those keys are integer keys */ |
| 386 | 351 | totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ |
| r242899 | r242900 | |
| 401 | 366 | |
| 402 | 367 | |
| 403 | 368 | Table *luaH_new (lua_State *L) { |
| 404 | GCObject *o = luaC_newobj(L, LUA_TTABLE, sizeof(Table)); | |
| 405 | Table *t = gco2t(o); | |
| 369 | Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; | |
| 406 | 370 | t->metatable = NULL; |
| 407 | 371 | t->flags = cast_byte(~0); |
| 408 | 372 | t->array = NULL; |
| r242899 | r242900 | |
| 440 | 404 | */ |
| 441 | 405 | TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { |
| 442 | 406 | Node *mp; |
| 443 | TValue aux; | |
| 444 | 407 | if (ttisnil(key)) luaG_runerror(L, "table index is nil"); |
| 445 | else if (ttisfloat(key)) { | |
| 446 | lua_Number n = fltvalue(key); | |
| 447 | lua_Integer k; | |
| 448 | if (luai_numisnan(n)) | |
| 449 | luaG_runerror(L, "table index is NaN"); | |
| 450 | if (numisinteger(n, &k)) { /* index is int? */ | |
| 451 | setivalue(&aux, k); | |
| 452 | key = &aux; /* insert it as an integer */ | |
| 453 | } | |
| 454 | } | |
| 408 | else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) | |
| 409 | luaG_runerror(L, "table index is NaN"); | |
| 455 | 410 | mp = mainposition(t, key); |
| 456 | 411 | if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ |
| 457 | 412 | Node *othern; |
| 458 | Node *f = getfreepos(t); /* get a free place */ | |
| 459 | if (f == NULL) { /* cannot find a free place? */ | |
| 413 | Node *n = getfreepos(t); /* get a free place */ | |
| 414 | if (n == NULL) { /* cannot find a free place? */ | |
| 460 | 415 | rehash(L, t, key); /* grow table */ |
| 461 | /* whatever called 'newkey' take | |
| 416 | /* whatever called 'newkey' take care of TM cache and GC barrier */ | |
| 462 | 417 | return luaH_set(L, t, key); /* insert key into grown table */ |
| 463 | 418 | } |
| 464 | lua_assert(!isdummy( | |
| 419 | lua_assert(!isdummy(n)); | |
| 465 | 420 | othern = mainposition(t, gkey(mp)); |
| 466 | 421 | if (othern != mp) { /* is colliding node out of its main position? */ |
| 467 | 422 | /* yes; move colliding node into free position */ |
| 468 | while (othern + gnext(othern) != mp) /* find previous */ | |
| 469 | othern += gnext(othern); | |
| 470 | gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */ | |
| 471 | *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ | |
| 472 | if (gnext(mp) != 0) { | |
| 473 | gnext(f) += cast_int(mp - f); /* correct 'next' */ | |
| 474 | gnext(mp) = 0; /* now 'mp' is free */ | |
| 475 | } | |
| 423 | while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ | |
| 424 | gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ | |
| 425 | *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ | |
| 426 | gnext(mp) = NULL; /* now `mp' is free */ | |
| 476 | 427 | setnilvalue(gval(mp)); |
| 477 | 428 | } |
| 478 | 429 | else { /* colliding node is in its own main position */ |
| 479 | 430 | /* new node will go into free position */ |
| 480 | if (gnext(mp) != 0) | |
| 481 | gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */ | |
| 482 | else lua_assert(gnext(f) == 0); | |
| 483 | gnext(mp) = cast_int(f - mp); | |
| 484 | mp = f; | |
| 431 | gnext(n) = gnext(mp); /* chain new position */ | |
| 432 | gnext(mp) = n; | |
| 433 | mp = n; | |
| 485 | 434 | } |
| 486 | 435 | } |
| 487 | setnodekey(L, &mp->i_key, key); | |
| 488 | luaC_barrierback(L, t, key); | |
| 436 | setobj2t(L, gkey(mp), key); | |
| 437 | luaC_barrierback(L, obj2gco(t), key); | |
| 489 | 438 | lua_assert(ttisnil(gval(mp))); |
| 490 | 439 | return gval(mp); |
| 491 | 440 | } |
| r242899 | r242900 | |
| 494 | 443 | /* |
| 495 | 444 | ** search function for integers |
| 496 | 445 | */ |
| 497 | const TValue *luaH_getint (Table *t, | |
| 446 | const TValue *luaH_getint (Table *t, int key) { | |
| 498 | 447 | /* (1 <= key && key <= t->sizearray) */ |
| 499 | if (l_castS2U(key - 1) < t->sizearray) | |
| 500 | return &t->array[key - 1]; | |
| 448 | if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) | |
| 449 | return &t->array[key-1]; | |
| 501 | 450 | else { |
| 502 | Node *n = hashint(t, key); | |
| 503 | for (;;) { /* check whether 'key' is somewhere in the chain */ | |
| 504 | if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) | |
| 451 | lua_Number nk = cast_num(key); | |
| 452 | Node *n = hashnum(t, nk); | |
| 453 | do { /* check whether `key' is somewhere in the chain */ | |
| 454 | if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) | |
| 505 | 455 | return gval(n); /* that's it */ |
| 506 | else { | |
| 507 | int nx = gnext(n); | |
| 508 | if (nx == 0) break; | |
| 509 | n += nx; | |
| 510 | } | |
| 511 | }; | |
| 456 | else n = gnext(n); | |
| 457 | } while (n); | |
| 512 | 458 | return luaO_nilobject; |
| 513 | 459 | } |
| 514 | 460 | } |
| r242899 | r242900 | |
| 519 | 465 | */ |
| 520 | 466 | const TValue *luaH_getstr (Table *t, TString *key) { |
| 521 | 467 | Node *n = hashstr(t, key); |
| 522 | lua_assert(key->tt == LUA_TSHRSTR); | |
| 523 | for (;;) { /* check whether 'key' is somewhere in the chain */ | |
| 524 | const TValue *k = gkey(n); | |
| 525 | if (ttisshrstring(k) && eqshrstr(tsvalue(k), key)) | |
| 468 | lua_assert(key->tsv.tt == LUA_TSHRSTR); | |
| 469 | do { /* check whether `key' is somewhere in the chain */ | |
| 470 | if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) | |
| 526 | 471 | return gval(n); /* that's it */ |
| 527 | else { | |
| 528 | int nx = gnext(n); | |
| 529 | if (nx == 0) break; | |
| 530 | n += nx; | |
| 531 | } | |
| 532 | }; | |
| 472 | else n = gnext(n); | |
| 473 | } while (n); | |
| 533 | 474 | return luaO_nilobject; |
| 534 | 475 | } |
| 535 | 476 | |
| r242899 | r242900 | |
| 539 | 480 | */ |
| 540 | 481 | const TValue *luaH_get (Table *t, const TValue *key) { |
| 541 | 482 | switch (ttype(key)) { |
| 542 | case LUA_TSHRSTR: return luaH_getstr(t, tsvalue(key)); | |
| 543 | case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); | |
| 483 | case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); | |
| 544 | 484 | case LUA_TNIL: return luaO_nilobject; |
| 545 | case LUA_TNUMFLT: { | |
| 546 | lua_Integer k; | |
| 547 | if (numisinteger(fltvalue(key), &k)) /* index is int? */ | |
| 485 | case LUA_TNUMBER: { | |
| 486 | int k; | |
| 487 | lua_Number n = nvalue(key); | |
| 488 | lua_number2int(k, n); | |
| 489 | if (luai_numeq(cast_num(k), n)) /* index is int? */ | |
| 548 | 490 | return luaH_getint(t, k); /* use specialized version */ |
| 549 | 491 | /* else go through */ |
| 550 | 492 | } |
| 551 | 493 | default: { |
| 552 | 494 | Node *n = mainposition(t, key); |
| 553 | | |
| 495 | do { /* check whether `key' is somewhere in the chain */ | |
| 554 | 496 | if (luaV_rawequalobj(gkey(n), key)) |
| 555 | 497 | return gval(n); /* that's it */ |
| 556 | else { | |
| 557 | int nx = gnext(n); | |
| 558 | if (nx == 0) break; | |
| 559 | n += nx; | |
| 560 | } | |
| 561 | }; | |
| 498 | else n = gnext(n); | |
| 499 | } while (n); | |
| 562 | 500 | return luaO_nilobject; |
| 563 | 501 | } |
| 564 | 502 | } |
| r242899 | r242900 | |
| 577 | 515 | } |
| 578 | 516 | |
| 579 | 517 | |
| 580 | void luaH_setint (lua_State *L, Table *t, | |
| 518 | void luaH_setint (lua_State *L, Table *t, int key, TValue *value) { | |
| 581 | 519 | const TValue *p = luaH_getint(t, key); |
| 582 | 520 | TValue *cell; |
| 583 | 521 | if (p != luaO_nilobject) |
| 584 | 522 | cell = cast(TValue *, p); |
| 585 | 523 | else { |
| 586 | 524 | TValue k; |
| 587 | set | |
| 525 | setnvalue(&k, cast_num(key)); | |
| 588 | 526 | cell = luaH_newkey(L, t, &k); |
| 589 | 527 | } |
| 590 | 528 | setobj2t(L, cell, value); |
| r242899 | r242900 | |
| 594 | 532 | static int unbound_search (Table *t, unsigned int j) { |
| 595 | 533 | unsigned int i = j; /* i is zero or a present index */ |
| 596 | 534 | j++; |
| 597 | /* find | |
| 535 | /* find `i' and `j' such that i is present and j is not */ | |
| 598 | 536 | while (!ttisnil(luaH_getint(t, j))) { |
| 599 | 537 | i = j; |
| 600 | if (j > cast(unsigned int, MAX_INT)/2) { /* overflow? */ | |
| 538 | j *= 2; | |
| 539 | if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ | |
| 601 | 540 | /* table was built with bad purposes: resort to linear search */ |
| 602 | 541 | i = 1; |
| 603 | 542 | while (!ttisnil(luaH_getint(t, i))) i++; |
| 604 | 543 | return i - 1; |
| 605 | 544 | } |
| 606 | j *= 2; | |
| 607 | 545 | } |
| 608 | 546 | /* now do a binary search between them */ |
| 609 | 547 | while (j - i > 1) { |
| r242899 | r242900 | |
| 616 | 554 | |
| 617 | 555 | |
| 618 | 556 | /* |
| 619 | ** Try to find a boundary in table | |
| 557 | ** Try to find a boundary in table `t'. A `boundary' is an integer index | |
| 620 | 558 | ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). |
| 621 | 559 | */ |
| 622 | 560 | int luaH_getn (Table *t) { |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ltable.h,v 2.2 | |
| 2 | ** $Id: ltable.h,v 2.16.1.2 2013/08/30 15:49:41 roberto Exp $ | |
| 3 | 3 | ** Lua tables (hash) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 11 | 11 | |
| 12 | 12 | |
| 13 | 13 | #define gnode(t,i) (&(t)->node[i]) |
| 14 | #define gkey(n) (&(n)->i_key.tvk) | |
| 14 | 15 | #define gval(n) (&(n)->i_val) |
| 15 | 16 | #define gnext(n) ((n)->i_key.nk.next) |
| 16 | 17 | |
| 17 | ||
| 18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ | |
| 19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) | |
| 20 | ||
| 21 | #define wgkey(n) (&(n)->i_key.nk) | |
| 22 | ||
| 23 | 18 | #define invalidateTMcache(t) ((t)->flags = 0) |
| 24 | 19 | |
| 25 | ||
| 26 | 20 | /* returns the key, given the value of a table entry */ |
| 27 | 21 | #define keyfromval(v) \ |
| 28 | 22 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) |
| 29 | 23 | |
| 30 | 24 | |
| 31 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); | |
| 32 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, | |
| 33 | TValue *value); | |
| 25 | LUAI_FUNC const TValue *luaH_getint (Table *t, int key); | |
| 26 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value); | |
| 34 | 27 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); |
| 35 | 28 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); |
| 36 | 29 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); |
| 37 | 30 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); |
| 38 | 31 | LUAI_FUNC Table *luaH_new (lua_State *L); |
| 39 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, | |
| 40 | unsigned int nhsize); | |
| 41 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); | |
| 32 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); | |
| 33 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); | |
| 42 | 34 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); |
| 43 | 35 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); |
| 44 | 36 | LUAI_FUNC int luaH_getn (Table *t); |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ltablib.c,v 1. | |
| 2 | ** $Id: ltablib.c,v 1.65.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Library for Table Manipulation |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define ltablib_c | |
| 8 | #define LUA_LIB | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <limits.h> | |
| 14 | 8 | #include <stddef.h> |
| 15 | 9 | |
| 10 | #define ltablib_c | |
| 11 | #define LUA_LIB | |
| 12 | ||
| 16 | 13 | #include "lua.h" |
| 17 | 14 | |
| 18 | 15 | #include "lauxlib.h" |
| 19 | 16 | #include "lualib.h" |
| 20 | 17 | |
| 21 | 18 | |
| 19 | #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n)) | |
| 22 | 20 | |
| 23 | /* | |
| 24 | ** Structure with table-access functions | |
| 25 | */ | |
| 26 | typedef struct { | |
| 27 | int (*geti) (lua_State *L, int idx, lua_Integer n); | |
| 28 | void (*seti) (lua_State *L, int idx, lua_Integer n); | |
| 29 | } TabA; | |
| 30 | 21 | |
| 31 | 22 | |
| 32 | /* | |
| 33 | ** Check that 'arg' has a table and set access functions in 'ta' to raw | |
| 34 | ** or non-raw according to the presence of corresponding metamethods. | |
| 35 | */ | |
| 36 | static void checktab (lua_State *L, int arg, TabA *ta) { | |
| 37 | ta->geti = NULL; ta->seti = NULL; | |
| 38 | if (lua_getmetatable(L, arg)) { | |
| 39 | lua_pushliteral(L, "__index"); /* 'index' metamethod */ | |
| 40 | if (lua_rawget(L, -2) != LUA_TNIL) | |
| 41 | ta->geti = lua_geti; | |
| 42 | lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */ | |
| 43 | if (lua_rawget(L, -3) != LUA_TNIL) | |
| 44 | ta->seti = lua_seti; | |
| 45 | lua_pop(L, 3); /* pop metatable plus both metamethods */ | |
| 46 | } | |
| 47 | if (ta->geti == NULL || ta->seti == NULL) { | |
| 48 | luaL_checktype(L, arg, LUA_TTABLE); /* must be table for raw methods */ | |
| 49 | if (ta->geti == NULL) ta->geti = lua_rawgeti; | |
| 50 | if (ta->seti == NULL) ta->seti = lua_rawseti; | |
| 51 | } | |
| 52 | } | |
| 53 | ||
| 54 | ||
| 55 | #define aux_getn(L,n,ta) (checktab(L, n, ta), luaL_len(L, n)) | |
| 56 | ||
| 57 | ||
| 58 | 23 | #if defined(LUA_COMPAT_MAXN) |
| 59 | 24 | static int maxn (lua_State *L) { |
| 60 | 25 | lua_Number max = 0; |
| r242899 | r242900 | |
| 74 | 39 | |
| 75 | 40 | |
| 76 | 41 | static int tinsert (lua_State *L) { |
| 77 | TabA ta; | |
| 78 | lua_Integer e = aux_getn(L, 1, &ta) + 1; /* first empty element */ | |
| 79 | lua_Integer pos; /* where to insert new element */ | |
| 42 | int e = aux_getn(L, 1) + 1; /* first empty element */ | |
| 43 | int pos; /* where to insert new element */ | |
| 80 | 44 | switch (lua_gettop(L)) { |
| 81 | 45 | case 2: { /* called with only 2 arguments */ |
| 82 | 46 | pos = e; /* insert new element at the end */ |
| 83 | 47 | break; |
| 84 | 48 | } |
| 85 | 49 | case 3: { |
| 86 | lua_Integer i; | |
| 87 | pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ | |
| 50 | int i; | |
| 51 | pos = luaL_checkint(L, 2); /* 2nd argument is the position */ | |
| 88 | 52 | luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); |
| 89 | 53 | for (i = e; i > pos; i--) { /* move up elements */ |
| 90 | (*ta.geti)(L, 1, i - 1); | |
| 91 | (*ta.seti)(L, 1, i); /* t[i] = t[i - 1] */ | |
| 54 | lua_rawgeti(L, 1, i-1); | |
| 55 | lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ | |
| 92 | 56 | } |
| 93 | 57 | break; |
| 94 | 58 | } |
| 95 | 59 | default: { |
| 96 | return luaL_error(L, "wrong number of arguments to | |
| 60 | return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); | |
| 97 | 61 | } |
| 98 | 62 | } |
| 99 | | |
| 63 | lua_rawseti(L, 1, pos); /* t[pos] = v */ | |
| 100 | 64 | return 0; |
| 101 | 65 | } |
| 102 | 66 | |
| 103 | 67 | |
| 104 | 68 | static int tremove (lua_State *L) { |
| 105 | TabA ta; | |
| 106 | lua_Integer size = aux_getn(L, 1, &ta); | |
| 107 | lua_Integer pos = luaL_optinteger(L, 2, size); | |
| 69 | int size = aux_getn(L, 1); | |
| 70 | int pos = luaL_optint(L, 2, size); | |
| 108 | 71 | if (pos != size) /* validate 'pos' if given */ |
| 109 | 72 | luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); |
| 110 | | |
| 73 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ | |
| 111 | 74 | for ( ; pos < size; pos++) { |
| 112 | (*ta.geti)(L, 1, pos + 1); | |
| 113 | (*ta.seti)(L, 1, pos); /* t[pos] = t[pos + 1] */ | |
| 75 | lua_rawgeti(L, 1, pos+1); | |
| 76 | lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ | |
| 114 | 77 | } |
| 115 | 78 | lua_pushnil(L); |
| 116 | | |
| 79 | lua_rawseti(L, 1, pos); /* t[pos] = nil */ | |
| 117 | 80 | return 1; |
| 118 | 81 | } |
| 119 | 82 | |
| 120 | 83 | |
| 121 | static int tmove (lua_State *L) { | |
| 122 | TabA ta; | |
| 123 | lua_Integer f = luaL_checkinteger(L, 2); | |
| 124 | lua_Integer e = luaL_checkinteger(L, 3); | |
| 125 | lua_Integer t = luaL_checkinteger(L, 4); | |
| 126 | int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ | |
| 127 | /* the following restriction avoids several problems with overflows */ | |
| 128 | luaL_argcheck(L, f > 0, 2, "initial position must be positive"); | |
| 129 | if (e >= f) { /* otherwise, nothing to move */ | |
| 130 | lua_Integer n, i; | |
| 131 | ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL) | |
| 132 | ? (luaL_checktype(L, 1, LUA_TTABLE), lua_rawgeti) | |
| 133 | : lua_geti; | |
| 134 | ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL) | |
| 135 | ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti) | |
| 136 | : lua_seti; | |
| 137 | n = e - f + 1; /* number of elements to move */ | |
| 138 | if (t > f) { | |
| 139 | for (i = n - 1; i >= 0; i--) { | |
| 140 | (*ta.geti)(L, 1, f + i); | |
| 141 | (*ta.seti)(L, tt, t + i); | |
| 142 | } | |
| 143 | } | |
| 144 | else { | |
| 145 | for (i = 0; i < n; i++) { | |
| 146 | (*ta.geti)(L, 1, f + i); | |
| 147 | (*ta.seti)(L, tt, t + i); | |
| 148 | } | |
| 149 | } | |
| 150 | } | |
| 151 | lua_pushvalue(L, tt); /* return "to table" */ | |
| 152 | return 1; | |
| 153 | } | |
| 154 | ||
| 155 | ||
| 156 | static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) { | |
| 157 | (*ta->geti)(L, 1, i); | |
| 84 | static void addfield (lua_State *L, luaL_Buffer *b, int i) { | |
| 85 | lua_rawgeti(L, 1, i); | |
| 158 | 86 | if (!lua_isstring(L, -1)) |
| 159 | luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", | |
| 160 | luaL_typename(L, -1), i); | |
| 87 | luaL_error(L, "invalid value (%s) at index %d in table for " | |
| 88 | LUA_QL("concat"), luaL_typename(L, -1), i); | |
| 161 | 89 | luaL_addvalue(b); |
| 162 | 90 | } |
| 163 | 91 | |
| 164 | 92 | |
| 165 | 93 | static int tconcat (lua_State *L) { |
| 166 | TabA ta; | |
| 167 | 94 | luaL_Buffer b; |
| 168 | 95 | size_t lsep; |
| 169 | | |
| 96 | int i, last; | |
| 170 | 97 | const char *sep = luaL_optlstring(L, 2, "", &lsep); |
| 171 | checktab(L, 1, &ta); | |
| 172 | i = luaL_optinteger(L, 3, 1); | |
| 173 | last = luaL_opt(L, luaL_checkinteger, 4, luaL_len(L, 1)); | |
| 98 | luaL_checktype(L, 1, LUA_TTABLE); | |
| 99 | i = luaL_optint(L, 3, 1); | |
| 100 | last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1)); | |
| 174 | 101 | luaL_buffinit(L, &b); |
| 175 | 102 | for (; i < last; i++) { |
| 176 | addfield(L, &b, | |
| 103 | addfield(L, &b, i); | |
| 177 | 104 | luaL_addlstring(&b, sep, lsep); |
| 178 | 105 | } |
| 179 | 106 | if (i == last) /* add last value (if interval was not empty) */ |
| 180 | addfield(L, &b, | |
| 107 | addfield(L, &b, i); | |
| 181 | 108 | luaL_pushresult(&b); |
| 182 | 109 | return 1; |
| 183 | 110 | } |
| r242899 | r242900 | |
| 190 | 117 | */ |
| 191 | 118 | |
| 192 | 119 | static int pack (lua_State *L) { |
| 193 | int i; | |
| 194 | 120 | int n = lua_gettop(L); /* number of elements to pack */ |
| 195 | 121 | lua_createtable(L, n, 1); /* create result table */ |
| 196 | lua_insert(L, 1); /* put it at index 1 */ | |
| 197 | for (i = n; i >= 1; i--) /* assign elements */ | |
| 198 | lua_rawseti(L, 1, i); | |
| 199 | 122 | lua_pushinteger(L, n); |
| 200 | lua_setfield(L, 1, "n"); /* t.n = number of elements */ | |
| 123 | lua_setfield(L, -2, "n"); /* t.n = number of elements */ | |
| 124 | if (n > 0) { /* at least one element? */ | |
| 125 | int i; | |
| 126 | lua_pushvalue(L, 1); | |
| 127 | lua_rawseti(L, -2, 1); /* insert first element */ | |
| 128 | lua_replace(L, 1); /* move table into index 1 */ | |
| 129 | for (i = n; i >= 2; i--) /* assign other elements */ | |
| 130 | lua_rawseti(L, 1, i); | |
| 131 | } | |
| 201 | 132 | return 1; /* return table */ |
| 202 | 133 | } |
| 203 | 134 | |
| 204 | 135 | |
| 205 | 136 | static int unpack (lua_State *L) { |
| 206 | TabA ta; | |
| 207 | lua_Integer i, e; | |
| 208 | lua_Unsigned n; | |
| 209 | checktab(L, 1, &ta); | |
| 210 | i = luaL_optinteger(L, 2, 1); | |
| 211 | e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); | |
| 137 | int i, e, n; | |
| 138 | luaL_checktype(L, 1, LUA_TTABLE); | |
| 139 | i = luaL_optint(L, 2, 1); | |
| 140 | e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); | |
| 212 | 141 | if (i > e) return 0; /* empty range */ |
| 213 | n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ | |
| 214 | if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) | |
| 142 | n = e - i + 1; /* number of elements */ | |
| 143 | if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ | |
| 215 | 144 | return luaL_error(L, "too many results to unpack"); |
| 216 | do { /* must have at least one element */ | |
| 217 | (*ta.geti)(L, 1, i); /* push arg[i..e] */ | |
| 218 | } while (i++ < e); | |
| 219 | ||
| 220 | return (int)n; | |
| 145 | lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ | |
| 146 | while (i++ < e) /* push arg[i + 1...e] */ | |
| 147 | lua_rawgeti(L, 1, i); | |
| 148 | return n; | |
| 221 | 149 | } |
| 222 | 150 | |
| 223 | 151 | /* }====================================================== */ |
| r242899 | r242900 | |
| 227 | 155 | /* |
| 228 | 156 | ** {====================================================== |
| 229 | 157 | ** Quicksort |
| 230 | ** (based on | |
| 158 | ** (based on `Algorithms in MODULA-3', Robert Sedgewick; | |
| 231 | 159 | ** Addison-Wesley, 1993.) |
| 232 | 160 | ** ======================================================= |
| 233 | 161 | */ |
| 234 | 162 | |
| 235 | 163 | |
| 236 | static void set2 (lua_State *L, TabA *ta, int i, int j) { | |
| 237 | (*ta->seti)(L, 1, i); | |
| 238 | (*ta->seti)(L, 1, j); | |
| 164 | static void set2 (lua_State *L, int i, int j) { | |
| 165 | lua_rawseti(L, 1, i); | |
| 166 | lua_rawseti(L, 1, j); | |
| 239 | 167 | } |
| 240 | 168 | |
| 241 | 169 | static int sort_comp (lua_State *L, int a, int b) { |
| r242899 | r242900 | |
| 243 | 171 | int res; |
| 244 | 172 | lua_pushvalue(L, 2); |
| 245 | 173 | lua_pushvalue(L, a-1); /* -1 to compensate function */ |
| 246 | lua_pushvalue(L, b-2); /* -2 to compensate function and | |
| 174 | lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ | |
| 247 | 175 | lua_call(L, 2, 1); |
| 248 | 176 | res = lua_toboolean(L, -1); |
| 249 | 177 | lua_pop(L, 1); |
| r242899 | r242900 | |
| 253 | 181 | return lua_compare(L, a, b, LUA_OPLT); |
| 254 | 182 | } |
| 255 | 183 | |
| 256 | static void auxsort (lua_State *L, | |
| 184 | static void auxsort (lua_State *L, int l, int u) { | |
| 257 | 185 | while (l < u) { /* for tail recursion */ |
| 258 | 186 | int i, j; |
| 259 | 187 | /* sort elements a[l], a[(l+u)/2] and a[u] */ |
| 260 | (*ta->geti)(L, 1, l); | |
| 261 | (*ta->geti)(L, 1, u); | |
| 188 | lua_rawgeti(L, 1, l); | |
| 189 | lua_rawgeti(L, 1, u); | |
| 262 | 190 | if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ |
| 263 | set2(L, | |
| 191 | set2(L, l, u); /* swap a[l] - a[u] */ | |
| 264 | 192 | else |
| 265 | 193 | lua_pop(L, 2); |
| 266 | 194 | if (u-l == 1) break; /* only 2 elements */ |
| 267 | 195 | i = (l+u)/2; |
| 268 | (*ta->geti)(L, 1, i); | |
| 269 | (*ta->geti)(L, 1, l); | |
| 196 | lua_rawgeti(L, 1, i); | |
| 197 | lua_rawgeti(L, 1, l); | |
| 270 | 198 | if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */ |
| 271 | set2(L, | |
| 199 | set2(L, i, l); | |
| 272 | 200 | else { |
| 273 | 201 | lua_pop(L, 1); /* remove a[l] */ |
| 274 | | |
| 202 | lua_rawgeti(L, 1, u); | |
| 275 | 203 | if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */ |
| 276 | set2(L, | |
| 204 | set2(L, i, u); | |
| 277 | 205 | else |
| 278 | 206 | lua_pop(L, 2); |
| 279 | 207 | } |
| 280 | 208 | if (u-l == 2) break; /* only 3 elements */ |
| 281 | | |
| 209 | lua_rawgeti(L, 1, i); /* Pivot */ | |
| 282 | 210 | lua_pushvalue(L, -1); |
| 283 | (*ta->geti)(L, 1, u-1); | |
| 284 | set2(L, ta, i, u-1); | |
| 211 | lua_rawgeti(L, 1, u-1); | |
| 212 | set2(L, i, u-1); | |
| 285 | 213 | /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ |
| 286 | 214 | i = l; j = u-1; |
| 287 | 215 | for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ |
| 288 | 216 | /* repeat ++i until a[i] >= P */ |
| 289 | while ( | |
| 217 | while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { | |
| 290 | 218 | if (i>=u) luaL_error(L, "invalid order function for sorting"); |
| 291 | 219 | lua_pop(L, 1); /* remove a[i] */ |
| 292 | 220 | } |
| 293 | 221 | /* repeat --j until a[j] <= P */ |
| 294 | while ( | |
| 222 | while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { | |
| 295 | 223 | if (j<=l) luaL_error(L, "invalid order function for sorting"); |
| 296 | 224 | lua_pop(L, 1); /* remove a[j] */ |
| 297 | 225 | } |
| r242899 | r242900 | |
| 299 | 227 | lua_pop(L, 3); /* pop pivot, a[i], a[j] */ |
| 300 | 228 | break; |
| 301 | 229 | } |
| 302 | set2(L, | |
| 230 | set2(L, i, j); | |
| 303 | 231 | } |
| 304 | (*ta->geti)(L, 1, u-1); | |
| 305 | (*ta->geti)(L, 1, i); | |
| 306 | set2(L, ta, u-1, i); /* swap pivot (a[u-1]) with a[i] */ | |
| 232 | lua_rawgeti(L, 1, u-1); | |
| 233 | lua_rawgeti(L, 1, i); | |
| 234 | set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */ | |
| 307 | 235 | /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ |
| 308 | 236 | /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ |
| 309 | 237 | if (i-l < u-i) { |
| r242899 | r242900 | |
| 312 | 240 | else { |
| 313 | 241 | j=i+1; i=u; u=j-2; |
| 314 | 242 | } |
| 315 | auxsort(L, | |
| 243 | auxsort(L, j, i); /* call recursively the smaller one */ | |
| 316 | 244 | } /* repeat the routine for the larger one */ |
| 317 | 245 | } |
| 318 | 246 | |
| 319 | 247 | static int sort (lua_State *L) { |
| 320 | TabA ta; | |
| 321 | int n = (int)aux_getn(L, 1, &ta); | |
| 322 | luaL_checkstack(L, 50, ""); /* assume array is smaller than 2^50 */ | |
| 248 | int n = aux_getn(L, 1); | |
| 249 | luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ | |
| 323 | 250 | if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ |
| 324 | 251 | luaL_checktype(L, 2, LUA_TFUNCTION); |
| 325 | lua_settop(L, 2); /* make sure there are two arguments */ | |
| 326 | auxsort(L, &ta, 1, n); | |
| 252 | lua_settop(L, 2); /* make sure there is two arguments */ | |
| 253 | auxsort(L, 1, n); | |
| 327 | 254 | return 0; |
| 328 | 255 | } |
| 329 | 256 | |
| r242899 | r242900 | |
| 339 | 266 | {"pack", pack}, |
| 340 | 267 | {"unpack", unpack}, |
| 341 | 268 | {"remove", tremove}, |
| 342 | {"move", tmove}, | |
| 343 | 269 | {"sort", sort}, |
| 344 | 270 | {NULL, NULL} |
| 345 | 271 | }; |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ltm.c,v 2. | |
| 2 | ** $Id: ltm.c,v 2.14.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Tag methods |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define ltm_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <string.h> |
| 14 | 9 | |
| 10 | #define ltm_c | |
| 11 | #define LUA_CORE | |
| 12 | ||
| 15 | 13 | #include "lua.h" |
| 16 | 14 | |
| 17 | #include "ldebug.h" | |
| 18 | #include "ldo.h" | |
| 19 | 15 | #include "lobject.h" |
| 20 | 16 | #include "lstate.h" |
| 21 | 17 | #include "lstring.h" |
| 22 | 18 | #include "ltable.h" |
| 23 | 19 | #include "ltm.h" |
| 24 | #include "lvm.h" | |
| 25 | 20 | |
| 26 | 21 | |
| 27 | 22 | static const char udatatypename[] = "userdata"; |
| r242899 | r242900 | |
| 30 | 25 | "no value", |
| 31 | 26 | "nil", "boolean", udatatypename, "number", |
| 32 | 27 | "string", "table", "function", udatatypename, "thread", |
| 33 | "proto" /* th | |
| 28 | "proto", "upval" /* these last two cases are used for tests only */ | |
| 34 | 29 | }; |
| 35 | 30 | |
| 36 | 31 | |
| r242899 | r242900 | |
| 38 | 33 | static const char *const luaT_eventname[] = { /* ORDER TM */ |
| 39 | 34 | "__index", "__newindex", |
| 40 | 35 | "__gc", "__mode", "__len", "__eq", |
| 41 | "__add", "__sub", "__mul", "__mod", "__pow", | |
| 42 | "__div", "__idiv", | |
| 43 | "__band", "__bor", "__bxor", "__shl", "__shr", | |
| 44 | "__unm", "__bnot", "__lt", "__le", | |
| 36 | "__add", "__sub", "__mul", "__div", "__mod", | |
| 37 | "__pow", "__unm", "__lt", "__le", | |
| 45 | 38 | "__concat", "__call" |
| 46 | 39 | }; |
| 47 | 40 | int i; |
| 48 | 41 | for (i=0; i<TM_N; i++) { |
| 49 | 42 | G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); |
| 50 | lua | |
| 43 | luaS_fix(G(L)->tmname[i]); /* never collect these names */ | |
| 51 | 44 | } |
| 52 | 45 | } |
| 53 | 46 | |
| r242899 | r242900 | |
| 69 | 62 | |
| 70 | 63 | const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { |
| 71 | 64 | Table *mt; |
| 72 | switch (ttn | |
| 65 | switch (ttypenv(o)) { | |
| 73 | 66 | case LUA_TTABLE: |
| 74 | 67 | mt = hvalue(o)->metatable; |
| 75 | 68 | break; |
| r242899 | r242900 | |
| 77 | 70 | mt = uvalue(o)->metatable; |
| 78 | 71 | break; |
| 79 | 72 | default: |
| 80 | mt = G(L)->mt[ttn | |
| 73 | mt = G(L)->mt[ttypenv(o)]; | |
| 81 | 74 | } |
| 82 | 75 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); |
| 83 | 76 | } |
| 84 | 77 | |
| 85 | ||
| 86 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, | |
| 87 | const TValue *p2, TValue *p3, int hasres) { | |
| 88 | ptrdiff_t result = savestack(L, p3); | |
| 89 | setobj2s(L, L->top++, f); /* push function (assume EXTRA_STACK) */ | |
| 90 | setobj2s(L, L->top++, p1); /* 1st argument */ | |
| 91 | setobj2s(L, L->top++, p2); /* 2nd argument */ | |
| 92 | if (!hasres) /* no result? 'p3' is third argument */ | |
| 93 | setobj2s(L, L->top++, p3); /* 3rd argument */ | |
| 94 | /* metamethod may yield only when called from Lua code */ | |
| 95 | luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); | |
| 96 | if (hasres) { /* if has result, move it to its place */ | |
| 97 | p3 = restorestack(L, result); | |
| 98 | setobjs2s(L, p3, --L->top); | |
| 99 | } | |
| 100 | } | |
| 101 | ||
| 102 | ||
| 103 | int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, | |
| 104 | StkId res, TMS event) { | |
| 105 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ | |
| 106 | if (ttisnil(tm)) | |
| 107 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | |
| 108 | if (ttisnil(tm)) return 0; | |
| 109 | luaT_callTM(L, tm, p1, p2, res, 1); | |
| 110 | return 1; | |
| 111 | } | |
| 112 | ||
| 113 | ||
| 114 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | |
| 115 | StkId res, TMS event) { | |
| 116 | if (!luaT_callbinTM(L, p1, p2, res, event)) { | |
| 117 | switch (event) { | |
| 118 | case TM_CONCAT: | |
| 119 | luaG_concaterror(L, p1, p2); | |
| 120 | case TM_BAND: case TM_BOR: case TM_BXOR: | |
| 121 | case TM_SHL: case TM_SHR: case TM_BNOT: { | |
| 122 | lua_Number dummy; | |
| 123 | if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) | |
| 124 | luaG_tointerror(L, p1, p2); | |
| 125 | else | |
| 126 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); | |
| 127 | /* else go through */ | |
| 128 | } | |
| 129 | default: | |
| 130 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); | |
| 131 | } | |
| 132 | } | |
| 133 | } | |
| 134 | ||
| 135 | ||
| 136 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, | |
| 137 | TMS event) { | |
| 138 | if (!luaT_callbinTM(L, p1, p2, L->top, event)) | |
| 139 | return -1; /* no metamethod */ | |
| 140 | else | |
| 141 | return !l_isfalse(L->top); | |
| 142 | } | |
| 143 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: ltm.h,v 2. | |
| 2 | ** $Id: ltm.h,v 2.11.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Tag methods |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 13 | 13 | |
| 14 | 14 | /* |
| 15 | 15 | * WARNING: if you change the order of this enumeration, |
| 16 | * grep "ORDER TM" | |
| 16 | * grep "ORDER TM" | |
| 17 | 17 | */ |
| 18 | 18 | typedef enum { |
| 19 | 19 | TM_INDEX, |
| r242899 | r242900 | |
| 21 | 21 | TM_GC, |
| 22 | 22 | TM_MODE, |
| 23 | 23 | TM_LEN, |
| 24 | TM_EQ, /* last tag method with fast access */ | |
| 24 | TM_EQ, /* last tag method with `fast' access */ | |
| 25 | 25 | TM_ADD, |
| 26 | 26 | TM_SUB, |
| 27 | 27 | TM_MUL, |
| 28 | TM_DIV, | |
| 28 | 29 | TM_MOD, |
| 29 | 30 | TM_POW, |
| 30 | TM_DIV, | |
| 31 | TM_IDIV, | |
| 32 | TM_BAND, | |
| 33 | TM_BOR, | |
| 34 | TM_BXOR, | |
| 35 | TM_SHL, | |
| 36 | TM_SHR, | |
| 37 | 31 | TM_UNM, |
| 38 | TM_BNOT, | |
| 39 | 32 | TM_LT, |
| 40 | 33 | TM_LE, |
| 41 | 34 | TM_CONCAT, |
| r242899 | r242900 | |
| 51 | 44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) |
| 52 | 45 | |
| 53 | 46 | #define ttypename(x) luaT_typenames_[(x) + 1] |
| 54 | #define objtypename(x) ttypename(ttn | |
| 47 | #define objtypename(x) ttypename(ttypenv(x)) | |
| 55 | 48 | |
| 56 | 49 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; |
| 57 | 50 | |
| r242899 | r242900 | |
| 61 | 54 | TMS event); |
| 62 | 55 | LUAI_FUNC void luaT_init (lua_State *L); |
| 63 | 56 | |
| 64 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, | |
| 65 | const TValue *p2, TValue *p3, int hasres); | |
| 66 | LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, | |
| 67 | StkId res, TMS event); | |
| 68 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | |
| 69 | StkId res, TMS event); | |
| 70 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, | |
| 71 | const TValue *p2, TMS event); | |
| 72 | ||
| 73 | ||
| 74 | ||
| 75 | 57 | #endif |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lua.c,v 1.2 | |
| 2 | ** $Id: lua.c,v 1.206.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lua stand-alone interpreter |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lua_c | |
| 8 | 7 | |
| 9 | #include "lprefix.h" | |
| 10 | ||
| 11 | ||
| 12 | 8 | #include <signal.h> |
| 13 | 9 | #include <stdio.h> |
| 14 | 10 | #include <stdlib.h> |
| 15 | 11 | #include <string.h> |
| 16 | 12 | |
| 13 | #define lua_c | |
| 14 | ||
| 17 | 15 | #include "lua.h" |
| 18 | 16 | |
| 19 | 17 | #include "lauxlib.h" |
| r242899 | r242900 | |
| 33 | 31 | #define LUA_MAXINPUT 512 |
| 34 | 32 | #endif |
| 35 | 33 | |
| 36 | #if !defined(LUA_INIT_VAR) | |
| 37 | #define LUA_INIT_VAR "LUA_INIT" | |
| 34 | #if !defined(LUA_INIT) | |
| 35 | #define LUA_INIT "LUA_INIT" | |
| 38 | 36 | #endif |
| 39 | 37 | |
| 40 | #define LUA_INITVARVERSION \ | |
| 41 | LUA_INIT_VAR "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR | |
| 38 | #define LUA_INITVERSION \ | |
| 39 | LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR | |
| 42 | 40 | |
| 43 | 41 | |
| 44 | 42 | /* |
| 45 | 43 | ** lua_stdin_is_tty detects whether the standard input is a 'tty' (that |
| 46 | 44 | ** is, whether we're running lua interactively). |
| 47 | 45 | */ |
| 48 | #if !defined(lua_stdin_is_tty) /* { */ | |
| 49 | ||
| 50 | #if defined(LUA_USE_POSIX) /* { */ | |
| 51 | ||
| 46 | #if defined(LUA_USE_ISATTY) | |
| 52 | 47 | #include <unistd.h> |
| 53 | 48 | #define lua_stdin_is_tty() isatty(0) |
| 54 | ||
| 55 | #elif defined(LUA_USE_WINDOWS) /* }{ */ | |
| 56 | ||
| 49 | #elif defined(LUA_WIN) | |
| 57 | 50 | #include <io.h> |
| 51 | #include <stdio.h> | |
| 58 | 52 | #define lua_stdin_is_tty() _isatty(_fileno(stdin)) |
| 59 | ||
| 60 | #else /* }{ */ | |
| 61 | ||
| 62 | /* ISO C definition */ | |
| 53 | #else | |
| 63 | 54 | #define lua_stdin_is_tty() 1 /* assume stdin is a tty */ |
| 55 | #endif | |
| 64 | 56 | |
| 65 | #endif /* } */ | |
| 66 | 57 | |
| 67 | #endif /* } */ | |
| 68 | ||
| 69 | ||
| 70 | 58 | /* |
| 71 | 59 | ** lua_readline defines how to show a prompt and then read a line from |
| 72 | 60 | ** the standard input. |
| 73 | 61 | ** lua_saveline defines how to "save" a read line in a "history". |
| 74 | 62 | ** lua_freeline defines how to free a line read by lua_readline. |
| 75 | 63 | */ |
| 76 | #if | |
| 64 | #if defined(LUA_USE_READLINE) | |
| 77 | 65 | |
| 78 | #if defined(LUA_USE_READLINE) /* { */ | |
| 79 | ||
| 66 | #include <stdio.h> | |
| 80 | 67 | #include <readline/readline.h> |
| 81 | 68 | #include <readline/history.h> |
| 82 | 69 | #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) |
| r242899 | r242900 | |
| 85 | 72 | add_history(lua_tostring(L, idx)); /* add it to history */ |
| 86 | 73 | #define lua_freeline(L,b) ((void)L, free(b)) |
| 87 | 74 | |
| 88 | #el | |
| 75 | #elif !defined(lua_readline) | |
| 89 | 76 | |
| 90 | 77 | #define lua_readline(L,b,p) \ |
| 91 | 78 | ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ |
| r242899 | r242900 | |
| 93 | 80 | #define lua_saveline(L,idx) { (void)L; (void)idx; } |
| 94 | 81 | #define lua_freeline(L,b) { (void)L; (void)b; } |
| 95 | 82 | |
| 96 | #endif | |
| 83 | #endif | |
| 97 | 84 | |
| 98 | #endif /* } */ | |
| 99 | 85 | |
| 100 | 86 | |
| 101 | 87 | |
| 102 | ||
| 103 | 88 | static lua_State *globalL = NULL; |
| 104 | 89 | |
| 105 | 90 | static const char *progname = LUA_PROGNAME; |
| 106 | 91 | |
| 107 | 92 | |
| 108 | /* | |
| 109 | ** Hook set by signal function to stop the interpreter. | |
| 110 | */ | |
| 93 | ||
| 111 | 94 | static void lstop (lua_State *L, lua_Debug *ar) { |
| 112 | 95 | (void)ar; /* unused arg. */ |
| 113 | lua_sethook(L, NULL, 0, 0); | |
| 96 | lua_sethook(L, NULL, 0, 0); | |
| 114 | 97 | luaL_error(L, "interrupted!"); |
| 115 | 98 | } |
| 116 | 99 | |
| 117 | 100 | |
| 118 | /* | |
| 119 | ** Function to be called at a C signal. Because a C signal cannot | |
| 120 | ** just change a Lua state (as there is no proper synchronization), | |
| 121 | ** this function only sets a hook that, when called, will stop the | |
| 122 | ** interpreter. | |
| 123 | */ | |
| 124 | 101 | static void laction (int i) { |
| 125 | signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */ | |
| 102 | signal(i, SIG_DFL); /* if another SIGINT happens before lstop, | |
| 103 | terminate process (default action) */ | |
| 126 | 104 | lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); |
| 127 | 105 | } |
| 128 | 106 | |
| 129 | 107 | |
| 130 | 108 | static void print_usage (const char *badoption) { |
| 131 | lua_writestringerror("%s: ", progname); | |
| 109 | luai_writestringerror("%s: ", progname); | |
| 132 | 110 | if (badoption[1] == 'e' || badoption[1] == 'l') |
| 133 | lua_writestringerror("'%s' needs argument\n", badoption); | |
| 111 | luai_writestringerror("'%s' needs argument\n", badoption); | |
| 134 | 112 | else |
| 135 | lua_writestringerror("unrecognized option '%s'\n", badoption); | |
| 136 | lua_writestringerror( | |
| 113 | luai_writestringerror("unrecognized option '%s'\n", badoption); | |
| 114 | luai_writestringerror( | |
| 137 | 115 | "usage: %s [options] [script [args]]\n" |
| 138 | 116 | "Available options are:\n" |
| 139 | " -e stat execute string 'stat'\n" | |
| 140 | " -i enter interactive mode after executing 'script'\n" | |
| 141 | " -l name require library 'name'\n" | |
| 117 | " -e stat execute string " LUA_QL("stat") "\n" | |
| 118 | " -i enter interactive mode after executing " LUA_QL("script") "\n" | |
| 119 | " -l name require library " LUA_QL("name") "\n" | |
| 142 | 120 | " -v show version information\n" |
| 143 | 121 | " -E ignore environment variables\n" |
| 144 | 122 | " -- stop handling options\n" |
| r242899 | r242900 | |
| 148 | 126 | } |
| 149 | 127 | |
| 150 | 128 | |
| 151 | /* | |
| 152 | ** Prints an error message, adding the program name in front of it | |
| 153 | ** (if present) | |
| 154 | */ | |
| 155 | 129 | static void l_message (const char *pname, const char *msg) { |
| 156 | if (pname) lua_writestringerror("%s: ", pname); | |
| 157 | lua_writestringerror("%s\n", msg); | |
| 130 | if (pname) luai_writestringerror("%s: ", pname); | |
| 131 | luai_writestringerror("%s\n", msg); | |
| 158 | 132 | } |
| 159 | 133 | |
| 160 | 134 | |
| 161 | /* | |
| 162 | ** Check whether 'status' is not OK and, if so, prints the error | |
| 163 | ** message on the top of the stack. It assumes that the error object | |
| 164 | ** is a string, as it was either generated by Lua or by 'msghandler'. | |
| 165 | */ | |
| 166 | 135 | static int report (lua_State *L, int status) { |
| 167 | if (status != LUA_OK) { | |
| 136 | if (status != LUA_OK && !lua_isnil(L, -1)) { | |
| 168 | 137 | const char *msg = lua_tostring(L, -1); |
| 138 | if (msg == NULL) msg = "(error object is not a string)"; | |
| 169 | 139 | l_message(progname, msg); |
| 170 | lua_pop(L, 1); /* remove message */ | |
| 140 | lua_pop(L, 1); | |
| 141 | /* force a complete garbage collection in case of errors */ | |
| 142 | lua_gc(L, LUA_GCCOLLECT, 0); | |
| 171 | 143 | } |
| 172 | 144 | return status; |
| 173 | 145 | } |
| 174 | 146 | |
| 175 | 147 | |
| 176 | /* | |
| 177 | ** Message handler used to run all chunks | |
| 178 | */ | |
| 179 | static int msghandler (lua_State *L) { | |
| 148 | /* the next function is called unprotected, so it must avoid errors */ | |
| 149 | static void finalreport (lua_State *L, int status) { | |
| 150 | if (status != LUA_OK) { | |
| 151 | const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1) | |
| 152 | : NULL; | |
| 153 | if (msg == NULL) msg = "(error object is not a string)"; | |
| 154 | l_message(progname, msg); | |
| 155 | lua_pop(L, 1); | |
| 156 | } | |
| 157 | } | |
| 158 | ||
| 159 | ||
| 160 | static int traceback (lua_State *L) { | |
| 180 | 161 | const char *msg = lua_tostring(L, 1); |
| 181 | if (msg == NULL) { /* is error object not a string? */ | |
| 182 | if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */ | |
| 183 | lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */ | |
| 184 | return 1; /* that is the message */ | |
| 185 | else | |
| 186 | msg = lua_pushfstring(L, "(error object is a %s value)", | |
| 187 | luaL_typename(L, 1)); | |
| 162 | if (msg) | |
| 163 | luaL_traceback(L, L, msg, 1); | |
| 164 | else if (!lua_isnoneornil(L, 1)) { /* is there an error object? */ | |
| 165 | if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */ | |
| 166 | lua_pushliteral(L, "(no error message)"); | |
| 188 | 167 | } |
| 189 | luaL_traceback(L, L, msg, 1); /* append a standard traceback */ | |
| 190 | return 1; /* return the traceback */ | |
| 168 | return 1; | |
| 191 | 169 | } |
| 192 | 170 | |
| 193 | 171 | |
| 194 | /* | |
| 195 | ** Interface to 'lua_pcall', which sets appropriate message function | |
| 196 | ** and C-signal handler. Used to run all chunks. | |
| 197 | */ | |
| 198 | 172 | static int docall (lua_State *L, int narg, int nres) { |
| 199 | 173 | int status; |
| 200 | 174 | int base = lua_gettop(L) - narg; /* function index */ |
| 201 | lua_pushcfunction(L, msghandler); /* push message handler */ | |
| 202 | lua_insert(L, base); /* put it under function and args */ | |
| 175 | lua_pushcfunction(L, traceback); /* push traceback function */ | |
| 176 | lua_insert(L, base); /* put it under chunk and args */ | |
| 203 | 177 | globalL = L; /* to be available to 'laction' */ |
| 204 | signal(SIGINT, laction); | |
| 178 | signal(SIGINT, laction); | |
| 205 | 179 | status = lua_pcall(L, narg, nres, base); |
| 206 | signal(SIGINT, SIG_DFL); /* reset C-signal handler */ | |
| 207 | lua_remove(L, base); /* remove message handler from the stack */ | |
| 180 | signal(SIGINT, SIG_DFL); | |
| 181 | lua_remove(L, base); /* remove traceback function */ | |
| 208 | 182 | return status; |
| 209 | 183 | } |
| 210 | 184 | |
| 211 | 185 | |
| 212 | 186 | static void print_version (void) { |
| 213 | lua_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT)); | |
| 214 | lua_writeline(); | |
| 187 | luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT)); | |
| 188 | luai_writeline(); | |
| 215 | 189 | } |
| 216 | 190 | |
| 217 | 191 | |
| 218 | /* | |
| 219 | ** Create the 'arg' table, which stores all arguments from the | |
| 220 | ** command line ('argv'). It should be aligned so that, at index 0, | |
| 221 | ** it has 'argv[script]', which is the script name. The arguments | |
| 222 | ** to the script (everything after 'script') go to positive indices; | |
| 223 | ** other arguments (before the script name) go to negative indices. | |
| 224 | ** If there is no script name, assume interpreter's name as base. | |
| 225 | */ | |
| 226 | static void createargtable (lua_State *L, char **argv, int argc, int script) { | |
| 227 | int i, narg; | |
| 228 | if (script == argc) script = 0; /* no script name? */ | |
| 229 | narg = argc - (script + 1); /* number of positive indices */ | |
| 230 | lua_createtable(L, narg, script + 1); | |
| 231 | for (i = 0; i < argc; i++) { | |
| 192 | static int getargs (lua_State *L, char **argv, int n) { | |
| 193 | int narg; | |
| 194 | int i; | |
| 195 | int argc = 0; | |
| 196 | while (argv[argc]) argc++; /* count total number of arguments */ | |
| 197 | narg = argc - (n + 1); /* number of arguments to the script */ | |
| 198 | luaL_checkstack(L, narg + 3, "too many arguments to script"); | |
| 199 | for (i=n+1; i < argc; i++) | |
| 232 | 200 | lua_pushstring(L, argv[i]); |
| 233 | lua_rawseti(L, -2, i - script); | |
| 201 | lua_createtable(L, narg, n + 1); | |
| 202 | for (i=0; i < argc; i++) { | |
| 203 | lua_pushstring(L, argv[i]); | |
| 204 | lua_rawseti(L, -2, i - n); | |
| 234 | 205 | } |
| 235 | | |
| 206 | return narg; | |
| 236 | 207 | } |
| 237 | 208 | |
| 238 | 209 | |
| 239 | static int dochunk (lua_State *L, int status) { | |
| 210 | static int dofile (lua_State *L, const char *name) { | |
| 211 | int status = luaL_loadfile(L, name); | |
| 240 | 212 | if (status == LUA_OK) status = docall(L, 0, 0); |
| 241 | 213 | return report(L, status); |
| 242 | 214 | } |
| 243 | 215 | |
| 244 | 216 | |
| 245 | static int dofile (lua_State *L, const char *name) { | |
| 246 | return dochunk(L, luaL_loadfile(L, name)); | |
| 247 | } | |
| 248 | ||
| 249 | ||
| 250 | 217 | static int dostring (lua_State *L, const char *s, const char *name) { |
| 251 | return dochunk(L, luaL_loadbuffer(L, s, strlen(s), name)); | |
| 218 | int status = luaL_loadbuffer(L, s, strlen(s), name); | |
| 219 | if (status == LUA_OK) status = docall(L, 0, 0); | |
| 220 | return report(L, status); | |
| 252 | 221 | } |
| 253 | 222 | |
| 254 | 223 | |
| 255 | /* | |
| 256 | ** Calls 'require(name)' and stores the result in a global variable | |
| 257 | ** with the given name. | |
| 258 | */ | |
| 259 | 224 | static int dolibrary (lua_State *L, const char *name) { |
| 260 | 225 | int status; |
| 261 | 226 | lua_getglobal(L, "require"); |
| r242899 | r242900 | |
| 267 | 232 | } |
| 268 | 233 | |
| 269 | 234 | |
| 270 | /* | |
| 271 | ** Returns the string to be used as a prompt by the interpreter. | |
| 272 | */ | |
| 273 | 235 | static const char *get_prompt (lua_State *L, int firstline) { |
| 274 | 236 | const char *p; |
| 275 | 237 | lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); |
| r242899 | r242900 | |
| 282 | 244 | #define EOFMARK "<eof>" |
| 283 | 245 | #define marklen (sizeof(EOFMARK)/sizeof(char) - 1) |
| 284 | 246 | |
| 285 | ||
| 286 | /* | |
| 287 | ** Check whether 'status' signals a syntax error and the error | |
| 288 | ** message at the top of the stack ends with the above mark for | |
| 289 | ** incomplete statements. | |
| 290 | */ | |
| 291 | 247 | static int incomplete (lua_State *L, int status) { |
| 292 | 248 | if (status == LUA_ERRSYNTAX) { |
| 293 | 249 | size_t lmsg; |
| r242899 | r242900 | |
| 301 | 257 | } |
| 302 | 258 | |
| 303 | 259 | |
| 304 | /* | |
| 305 | ** Prompt the user, read a line, and push it into the Lua stack. | |
| 306 | */ | |
| 307 | 260 | static int pushline (lua_State *L, int firstline) { |
| 308 | 261 | char buffer[LUA_MAXINPUT]; |
| 309 | 262 | char *b = buffer; |
| 310 | 263 | size_t l; |
| 311 | 264 | const char *prmt = get_prompt(L, firstline); |
| 312 | 265 | int readstatus = lua_readline(L, b, prmt); |
| 266 | lua_pop(L, 1); /* remove result from 'get_prompt' */ | |
| 313 | 267 | if (readstatus == 0) |
| 314 | return 0; /* no input (prompt will be popped by caller) */ | |
| 315 | lua_pop(L, 1); /* remove prompt */ | |
| 268 | return 0; /* no input */ | |
| 316 | 269 | l = strlen(b); |
| 317 | 270 | if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ |
| 318 | 271 | b[l-1] = '\0'; /* remove it */ |
| 319 | if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */ | |
| 320 | lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */ | |
| 272 | if (firstline && b[0] == '=') /* first line starts with `=' ? */ | |
| 273 | lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ | |
| 321 | 274 | else |
| 322 | 275 | lua_pushstring(L, b); |
| 323 | 276 | lua_freeline(L, b); |
| r242899 | r242900 | |
| 325 | 278 | } |
| 326 | 279 | |
| 327 | 280 | |
| 328 | /* | |
| 329 | ** Try to compile line on the stack as 'return <line>'; on return, stack | |
| 330 | ** has either compiled chunk or original line (if compilation failed). | |
| 331 | */ | |
| 332 | static int addreturn (lua_State *L) { | |
| 333 | int status; | |
| 334 | size_t len; const char *line; | |
| 335 | lua_pushliteral(L, "return "); | |
| 336 | lua_pushvalue(L, -2); /* duplicate line */ | |
| 337 | lua_concat(L, 2); /* new line is "return ..." */ | |
| 338 | line = lua_tolstring(L, -1, &len); | |
| 339 | if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) | |
| 340 | lua_remove(L, -3); /* remove original line */ | |
| 341 | else | |
| 342 | lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */ | |
| 343 | return status; | |
| 344 | } | |
| 345 | ||
| 346 | ||
| 347 | /* | |
| 348 | ** Read multiple lines until a complete Lua statement | |
| 349 | */ | |
| 350 | static int multiline (lua_State *L) { | |
| 351 | for (;;) { /* repeat until gets a complete statement */ | |
| 352 | size_t len; | |
| 353 | const char *line = lua_tolstring(L, 1, &len); /* get what it has */ | |
| 354 | int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ | |
| 355 | if (!incomplete(L, status) || !pushline(L, 0)) | |
| 356 | return status; /* cannot or should not try to add continuation line */ | |
| 357 | lua_pushliteral(L, "\n"); /* add newline... */ | |
| 358 | lua_insert(L, -2); /* ...between the two lines */ | |
| 359 | lua_concat(L, 3); /* join them */ | |
| 360 | } | |
| 361 | } | |
| 362 | ||
| 363 | ||
| 364 | /* | |
| 365 | ** Read a line and try to load (compile) it first as an expression (by | |
| 366 | ** adding "return " in front of it) and second as a statement. Return | |
| 367 | ** the final status of load/call with the resulting function (if any) | |
| 368 | ** in the top of the stack. | |
| 369 | */ | |
| 370 | 281 | static int loadline (lua_State *L) { |
| 371 | 282 | int status; |
| 372 | 283 | lua_settop(L, 0); |
| 373 | 284 | if (!pushline(L, 1)) |
| 374 | 285 | return -1; /* no input */ |
| 375 | if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */ | |
| 376 | status = multiline(L); /* try as command, maybe with continuation lines */ | |
| 377 | lua_saveline(L, 1); /* keep history */ | |
| 378 | lua_remove(L, 1); /* remove line from the stack */ | |
| 379 | lua_assert(lua_gettop(L) == 1); | |
| 286 | for (;;) { /* repeat until gets a complete line */ | |
| 287 | size_t l; | |
| 288 | const char *line = lua_tolstring(L, 1, &l); | |
| 289 | status = luaL_loadbuffer(L, line, l, "=stdin"); | |
| 290 | if (!incomplete(L, status)) break; /* cannot try to add lines? */ | |
| 291 | if (!pushline(L, 0)) /* no more input? */ | |
| 292 | return -1; | |
| 293 | lua_pushliteral(L, "\n"); /* add a new line... */ | |
| 294 | lua_insert(L, -2); /* ...between the two lines */ | |
| 295 | lua_concat(L, 3); /* join them */ | |
| 296 | } | |
| 297 | lua_saveline(L, 1); | |
| 298 | lua_remove(L, 1); /* remove line */ | |
| 380 | 299 | return status; |
| 381 | 300 | } |
| 382 | 301 | |
| 383 | 302 | |
| 384 | /* | |
| 385 | ** Prints (calling the Lua 'print' function) any values on the stack | |
| 386 | */ | |
| 387 | static void l_print (lua_State *L) { | |
| 388 | int n = lua_gettop(L); | |
| 389 | if (n > 0) { /* any result to be printed? */ | |
| 390 | luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); | |
| 391 | lua_getglobal(L, "print"); | |
| 392 | lua_insert(L, 1); | |
| 393 | if (lua_pcall(L, n, 0, 0) != LUA_OK) | |
| 394 | l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)", | |
| 395 | lua_tostring(L, -1))); | |
| 396 | } | |
| 397 | } | |
| 398 | ||
| 399 | ||
| 400 | /* | |
| 401 | ** Do the REPL: repeatedly read (load) a line, evaluate (call) it, and | |
| 402 | ** print any results. | |
| 403 | */ | |
| 404 | static void doREPL (lua_State *L) { | |
| 303 | static void dotty (lua_State *L) { | |
| 405 | 304 | int status; |
| 406 | 305 | const char *oldprogname = progname; |
| 407 | progname = NULL; | |
| 306 | progname = NULL; | |
| 408 | 307 | while ((status = loadline(L)) != -1) { |
| 409 | if (status == LUA_OK) | |
| 410 | status = docall(L, 0, LUA_MULTRET); | |
| 411 | if (status == LUA_OK) l_print(L); | |
| 412 | else report(L, status); | |
| 308 | if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET); | |
| 309 | report(L, status); | |
| 310 | if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ | |
| 311 | luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); | |
| 312 | lua_getglobal(L, "print"); | |
| 313 | lua_insert(L, 1); | |
| 314 | if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK) | |
| 315 | l_message(progname, lua_pushfstring(L, | |
| 316 | "error calling " LUA_QL("print") " (%s)", | |
| 317 | lua_tostring(L, -1))); | |
| 318 | } | |
| 413 | 319 | } |
| 414 | 320 | lua_settop(L, 0); /* clear stack */ |
| 415 | lua_writeline(); | |
| 321 | luai_writeline(); | |
| 416 | 322 | progname = oldprogname; |
| 417 | 323 | } |
| 418 | 324 | |
| 419 | 325 | |
| 420 | /* | |
| 421 | ** Push on the stack the contents of table 'arg' from 1 to #arg | |
| 422 | */ | |
| 423 | static int pushargs (lua_State *L) { | |
| 424 | int i, n; | |
| 425 | if (lua_getglobal(L, "arg") != LUA_TTABLE) | |
| 426 | luaL_error(L, "'arg' is not a table"); | |
| 427 | n = (int)luaL_len(L, -1); | |
| 428 | luaL_checkstack(L, n + 3, "too many arguments to script"); | |
| 429 | for (i = 1; i <= n; i++) | |
| 430 | lua_rawgeti(L, -i, i); | |
| 431 | lua_remove(L, -i); /* remove table from the stack */ | |
| 432 | return n; | |
| 433 | } | |
| 434 | ||
| 435 | ||
| 436 | static int handle_script (lua_State *L, char **argv) { | |
| 326 | static int handle_script (lua_State *L, char **argv, int n) { | |
| 437 | 327 | int status; |
| 438 | const char *fname = argv[0]; | |
| 439 | if (strcmp(fname, "-") == 0 && strcmp(argv[-1], "--") != 0) | |
| 328 | const char *fname; | |
| 329 | int narg = getargs(L, argv, n); /* collect arguments */ | |
| 330 | lua_setglobal(L, "arg"); | |
| 331 | fname = argv[n]; | |
| 332 | if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) | |
| 440 | 333 | fname = NULL; /* stdin */ |
| 441 | 334 | status = luaL_loadfile(L, fname); |
| 442 | if (status == LUA_OK) { | |
| 443 | int n = pushargs(L); /* push arguments to script */ | |
| 444 | status = docall(L, n, LUA_MULTRET); | |
| 445 | } | |
| 335 | lua_insert(L, -(narg+1)); | |
| 336 | if (status == LUA_OK) | |
| 337 | status = docall(L, narg, LUA_MULTRET); | |
| 338 | else | |
| 339 | lua_pop(L, narg); | |
| 446 | 340 | return report(L, status); |
| 447 | 341 | } |
| 448 | 342 | |
| 449 | 343 | |
| 344 | /* check that argument has no extra characters at the end */ | |
| 345 | #define noextrachars(x) {if ((x)[2] != '\0') return -1;} | |
| 450 | 346 | |
| 451 | /* bits of various argument indicators in 'args' */ | |
| 452 | #define has_error 1 /* bad option */ | |
| 453 | #define has_i 2 /* -i */ | |
| 454 | #define has_v 4 /* -v */ | |
| 455 | #define has_e 8 /* -e */ | |
| 456 | #define has_E 16 /* -E */ | |
| 457 | 347 | |
| 458 | /* | |
| 459 | ** Traverses all arguments from 'argv', returning a mask with those | |
| 460 | ** needed before running any Lua code (or an error code if it finds | |
| 461 | ** any invalid argument). 'first' returns the first not-handled argument | |
| 462 | ** (either the script name or a bad argument in case of error). | |
| 463 | */ | |
| 464 | static int collectargs (char **argv, int *first) { | |
| 465 | int args = 0; | |
| 348 | /* indices of various argument indicators in array args */ | |
| 349 | #define has_i 0 /* -i */ | |
| 350 | #define has_v 1 /* -v */ | |
| 351 | #define has_e 2 /* -e */ | |
| 352 | #define has_E 3 /* -E */ | |
| 353 | ||
| 354 | #define num_has 4 /* number of 'has_*' */ | |
| 355 | ||
| 356 | ||
| 357 | static int collectargs (char **argv, int *args) { | |
| 466 | 358 | int i; |
| 467 | 359 | for (i = 1; argv[i] != NULL; i++) { |
| 468 | *first = i; | |
| 469 | 360 | if (argv[i][0] != '-') /* not an option? */ |
| 470 | return args; /* stop handling options */ | |
| 471 | switch (argv[i][1]) { /* else check option */ | |
| 472 | case '-': /* '--' */ | |
| 473 | if (argv[i][2] != '\0') /* extra characters after '--'? */ | |
| 474 | return has_error; /* invalid option */ | |
| 475 | *first = i + 1; | |
| 476 | return args; | |
| 477 | case '\0': /* '-' */ | |
| 478 | return args; /* script "name" is '-' */ | |
| 361 | return i; | |
| 362 | switch (argv[i][1]) { /* option */ | |
| 363 | case '-': | |
| 364 | noextrachars(argv[i]); | |
| 365 | return (argv[i+1] != NULL ? i+1 : 0); | |
| 366 | case '\0': | |
| 367 | return i; | |
| 479 | 368 | case 'E': |
| 480 | if (argv[i][2] != '\0') /* extra characters after 1st? */ | |
| 481 | return has_error; /* invalid option */ | |
| 482 | args |= has_E; | |
| 369 | args[has_E] = 1; | |
| 483 | 370 | break; |
| 484 | 371 | case 'i': |
| 485 | args |= has_i; /* goes through (-i implies -v) */ | |
| 372 | noextrachars(argv[i]); | |
| 373 | args[has_i] = 1; /* go through */ | |
| 486 | 374 | case 'v': |
| 487 | if (argv[i][2] != '\0') /* extra characters after 1st? */ | |
| 488 | return has_error; /* invalid option */ | |
| 489 | args |= has_v; | |
| 375 | noextrachars(argv[i]); | |
| 376 | args[has_v] = 1; | |
| 490 | 377 | break; |
| 491 | 378 | case 'e': |
| 492 | args | |
| 379 | args[has_e] = 1; /* go through */ | |
| 493 | 380 | case 'l': /* both options need an argument */ |
| 494 | 381 | if (argv[i][2] == '\0') { /* no concatenated argument? */ |
| 495 | 382 | i++; /* try next 'argv' */ |
| 496 | 383 | if (argv[i] == NULL || argv[i][0] == '-') |
| 497 | return | |
| 384 | return -(i - 1); /* no next argument or it is another option */ | |
| 498 | 385 | } |
| 499 | 386 | break; |
| 500 | default: /* invalid option */ | |
| 501 | return has_error; | |
| 387 | default: /* invalid option; return its index... */ | |
| 388 | return -i; /* ...as a negative value */ | |
| 502 | 389 | } |
| 503 | 390 | } |
| 504 | *first = i; /* no script name */ | |
| 505 | return args; | |
| 391 | return 0; | |
| 506 | 392 | } |
| 507 | 393 | |
| 508 | 394 | |
| 509 | /* | |
| 510 | ** Processes options 'e' and 'l', which involve running Lua code. | |
| 511 | ** Returns 0 if some code raises an error. | |
| 512 | */ | |
| 513 | 395 | static int runargs (lua_State *L, char **argv, int n) { |
| 514 | 396 | int i; |
| 515 | 397 | for (i = 1; i < n; i++) { |
| 516 | int status; | |
| 517 | int option = argv[i][1]; | |
| 518 | lua_assert(argv[i][0] == '-'); /* already checked */ | |
| 519 | if (option == 'e' || option == 'l') { | |
| 520 | const char *extra = argv[i] + 2; /* both options need an argument */ | |
| 521 | if (*extra == '\0') extra = argv[++i]; | |
| 522 | lua_assert(extra != NULL); | |
| 523 | if (option == 'e') | |
| 524 | status = dostring(L, extra, "=(command line)"); | |
| 525 | else | |
| 526 | status = dolibrary(L, extra); | |
| 527 | if (status != LUA_OK) return 0; | |
| 398 | lua_assert(argv[i][0] == '-'); | |
| 399 | switch (argv[i][1]) { /* option */ | |
| 400 | case 'e': { | |
| 401 | const char *chunk = argv[i] + 2; | |
| 402 | if (*chunk == '\0') chunk = argv[++i]; | |
| 403 | lua_assert(chunk != NULL); | |
| 404 | if (dostring(L, chunk, "=(command line)") != LUA_OK) | |
| 405 | return 0; | |
| 406 | break; | |
| 407 | } | |
| 408 | case 'l': { | |
| 409 | const char *filename = argv[i] + 2; | |
| 410 | if (*filename == '\0') filename = argv[++i]; | |
| 411 | lua_assert(filename != NULL); | |
| 412 | if (dolibrary(L, filename) != LUA_OK) | |
| 413 | return 0; /* stop if file fails */ | |
| 414 | break; | |
| 415 | } | |
| 416 | default: break; | |
| 528 | 417 | } |
| 529 | 418 | } |
| 530 | 419 | return 1; |
| r242899 | r242900 | |
| 532 | 421 | |
| 533 | 422 | |
| 534 | 423 | static int handle_luainit (lua_State *L) { |
| 535 | const char *name = "=" LUA_INITV | |
| 424 | const char *name = "=" LUA_INITVERSION; | |
| 536 | 425 | const char *init = getenv(name + 1); |
| 537 | 426 | if (init == NULL) { |
| 538 | name = "=" LUA_INIT | |
| 427 | name = "=" LUA_INIT; | |
| 539 | 428 | init = getenv(name + 1); /* try alternative name */ |
| 540 | 429 | } |
| 541 | 430 | if (init == NULL) return LUA_OK; |
| r242899 | r242900 | |
| 546 | 435 | } |
| 547 | 436 | |
| 548 | 437 | |
| 549 | /* | |
| 550 | ** Main body of stand-alone interpreter (to be called in protected mode). | |
| 551 | ** Reads the options and handles them all. | |
| 552 | */ | |
| 553 | 438 | static int pmain (lua_State *L) { |
| 554 | 439 | int argc = (int)lua_tointeger(L, 1); |
| 555 | 440 | char **argv = (char **)lua_touserdata(L, 2); |
| 556 | 441 | int script; |
| 557 | int args = collectargs(argv, &script); | |
| 558 | luaL_checkversion(L); /* check that interpreter has correct version */ | |
| 442 | int args[num_has]; | |
| 443 | args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0; | |
| 559 | 444 | if (argv[0] && argv[0][0]) progname = argv[0]; |
| 560 | if (args == has_error) { /* bad arg? */ | |
| 561 | print_usage(argv[script]); /* 'script' has index of bad arg. */ | |
| 445 | script = collectargs(argv, args); | |
| 446 | if (script < 0) { /* invalid arg? */ | |
| 447 | print_usage(argv[-script]); | |
| 562 | 448 | return 0; |
| 563 | 449 | } |
| 564 | if (args & has_v) /* option '-v'? */ | |
| 565 | print_version(); | |
| 566 | if (args & has_E) { /* option '-E'? */ | |
| 450 | if (args[has_v]) print_version(); | |
| 451 | if (args[has_E]) { /* option '-E'? */ | |
| 567 | 452 | lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ |
| 568 | 453 | lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); |
| 569 | 454 | } |
| 570 | luaL_openlibs(L); /* open standard libraries */ | |
| 571 | createargtable(L, argv, argc, script); /* create table 'arg' */ | |
| 572 | if (!(args & has_E)) { /* no option '-E'? */ | |
| 573 | if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */ | |
| 574 | return 0; /* error running LUA_INIT */ | |
| 575 | } | |
| 576 | if (!runargs(L, argv, script)) /* execute arguments -e and -l */ | |
| 577 | return 0; /* something failed */ | |
| 578 | if (script < argc && /* execute main script (if there is one) */ | |
| 579 | handle_script(L, argv + script) != LUA_OK) | |
| 580 | return 0; | |
| 581 | if (args & has_i) /* -i option? */ | |
| 582 | doREPL(L); /* do read-eval-print loop */ | |
| 583 | else if (script == argc && !(args & (has_e | has_v))) { /* no arguments? */ | |
| 584 | if (lua_stdin_is_tty()) { /* running in interactive mode? */ | |
| 455 | /* open standard libraries */ | |
| 456 | luaL_checkversion(L); | |
| 457 | lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ | |
| 458 | luaL_openlibs(L); /* open libraries */ | |
| 459 | lua_gc(L, LUA_GCRESTART, 0); | |
| 460 | if (!args[has_E] && handle_luainit(L) != LUA_OK) | |
| 461 | return 0; /* error running LUA_INIT */ | |
| 462 | /* execute arguments -e and -l */ | |
| 463 | if (!runargs(L, argv, (script > 0) ? script : argc)) return 0; | |
| 464 | /* execute main script (if there is one) */ | |
| 465 | if (script && handle_script(L, argv, script) != LUA_OK) return 0; | |
| 466 | if (args[has_i]) /* -i option? */ | |
| 467 | dotty(L); | |
| 468 | else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */ | |
| 469 | if (lua_stdin_is_tty()) { | |
| 585 | 470 | print_version(); |
| 586 | do | |
| 471 | dotty(L); | |
| 587 | 472 | } |
| 588 | 473 | else dofile(L, NULL); /* executes stdin as a file */ |
| 589 | 474 | } |
| r242899 | r242900 | |
| 599 | 484 | l_message(argv[0], "cannot create state: not enough memory"); |
| 600 | 485 | return EXIT_FAILURE; |
| 601 | 486 | } |
| 602 | lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */ | |
| 487 | /* call 'pmain' in protected mode */ | |
| 488 | lua_pushcfunction(L, &pmain); | |
| 603 | 489 | lua_pushinteger(L, argc); /* 1st argument */ |
| 604 | 490 | lua_pushlightuserdata(L, argv); /* 2nd argument */ |
| 605 | status = lua_pcall(L, 2, 1, 0); | |
| 491 | status = lua_pcall(L, 2, 1, 0); | |
| 606 | 492 | result = lua_toboolean(L, -1); /* get result */ |
| 607 | report(L, status); | |
| 493 | finalreport(L, status); | |
| 608 | 494 | lua_close(L); |
| 609 | 495 | return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; |
| 610 | 496 | } |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lua.h,v 1. | |
| 2 | ** $Id: lua.h,v 1.285.1.2 2013/11/11 12:09:16 roberto Exp $ | |
| 3 | 3 | ** Lua - A Scripting Language |
| 4 | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
| 5 | 5 | ** See Copyright Notice at the end of this file |
| r242899 | r242900 | |
| 17 | 17 | |
| 18 | 18 | |
| 19 | 19 | #define LUA_VERSION_MAJOR "5" |
| 20 | #define LUA_VERSION_MINOR "3" | |
| 21 | #define LUA_VERSION_NUM 503 | |
| 22 | #define LUA_VERSION_RELEASE "0" | |
| 20 | #define LUA_VERSION_MINOR "2" | |
| 21 | #define LUA_VERSION_NUM 502 | |
| 22 | #define LUA_VERSION_RELEASE "3" | |
| 23 | 23 | |
| 24 | 24 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR |
| 25 | 25 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE |
| 26 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-201 | |
| 26 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2013 Lua.org, PUC-Rio" | |
| 27 | 27 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" |
| 28 | 28 | |
| 29 | 29 | |
| 30 | 30 | /* mark for precompiled code ('<esc>Lua') */ |
| 31 | #define LUA_SIGNATURE "\ | |
| 31 | #define LUA_SIGNATURE "\033Lua" | |
| 32 | 32 | |
| 33 | 33 | /* option for multiple returns in 'lua_pcall' and 'lua_call' */ |
| 34 | 34 | #define LUA_MULTRET (-1) |
| r242899 | r242900 | |
| 53 | 53 | |
| 54 | 54 | typedef struct lua_State lua_State; |
| 55 | 55 | |
| 56 | typedef int (*lua_CFunction) (lua_State *L); | |
| 56 | 57 | |
| 58 | ||
| 57 | 59 | /* |
| 60 | ** functions that read/write blocks when loading/dumping Lua chunks | |
| 61 | */ | |
| 62 | typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); | |
| 63 | ||
| 64 | typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); | |
| 65 | ||
| 66 | ||
| 67 | /* | |
| 68 | ** prototype for memory-allocation functions | |
| 69 | */ | |
| 70 | typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); | |
| 71 | ||
| 72 | ||
| 73 | /* | |
| 58 | 74 | ** basic types |
| 59 | 75 | */ |
| 60 | 76 | #define LUA_TNONE (-1) |
| r242899 | r242900 | |
| 93 | 109 | /* unsigned integer type */ |
| 94 | 110 | typedef LUA_UNSIGNED lua_Unsigned; |
| 95 | 111 | |
| 96 | /* type for continuation-function contexts */ | |
| 97 | typedef LUA_KCONTEXT lua_KContext; | |
| 98 | 112 | |
| 99 | 113 | |
| 100 | 114 | /* |
| 101 | ** Type for C functions registered with Lua | |
| 102 | */ | |
| 103 | typedef int (*lua_CFunction) (lua_State *L); | |
| 104 | ||
| 105 | /* | |
| 106 | ** Type for continuation functions | |
| 107 | */ | |
| 108 | typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); | |
| 109 | ||
| 110 | ||
| 111 | /* | |
| 112 | ** Type for functions that read/write blocks when loading/dumping Lua chunks | |
| 113 | */ | |
| 114 | typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); | |
| 115 | ||
| 116 | typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud); | |
| 117 | ||
| 118 | ||
| 119 | /* | |
| 120 | ** Type for memory-allocation functions | |
| 121 | */ | |
| 122 | typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); | |
| 123 | ||
| 124 | ||
| 125 | ||
| 126 | /* | |
| 127 | 115 | ** generic extra include file |
| 128 | 116 | */ |
| 129 | 117 | #if defined(LUA_USER_H) |
| r242899 | r242900 | |
| 157 | 145 | LUA_API int (lua_gettop) (lua_State *L); |
| 158 | 146 | LUA_API void (lua_settop) (lua_State *L, int idx); |
| 159 | 147 | LUA_API void (lua_pushvalue) (lua_State *L, int idx); |
| 160 | LUA_API void (lua_rotate) (lua_State *L, int idx, int n); | |
| 148 | LUA_API void (lua_remove) (lua_State *L, int idx); | |
| 149 | LUA_API void (lua_insert) (lua_State *L, int idx); | |
| 150 | LUA_API void (lua_replace) (lua_State *L, int idx); | |
| 161 | 151 | LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); |
| 162 | LUA_API int (lua_checkstack) (lua_State *L, int | |
| 152 | LUA_API int (lua_checkstack) (lua_State *L, int sz); | |
| 163 | 153 | |
| 164 | 154 | LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); |
| 165 | 155 | |
| r242899 | r242900 | |
| 171 | 161 | LUA_API int (lua_isnumber) (lua_State *L, int idx); |
| 172 | 162 | LUA_API int (lua_isstring) (lua_State *L, int idx); |
| 173 | 163 | LUA_API int (lua_iscfunction) (lua_State *L, int idx); |
| 174 | LUA_API int (lua_isinteger) (lua_State *L, int idx); | |
| 175 | 164 | LUA_API int (lua_isuserdata) (lua_State *L, int idx); |
| 176 | 165 | LUA_API int (lua_type) (lua_State *L, int idx); |
| 177 | 166 | LUA_API const char *(lua_typename) (lua_State *L, int tp); |
| 178 | 167 | |
| 179 | 168 | LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); |
| 180 | 169 | LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); |
| 170 | LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum); | |
| 181 | 171 | LUA_API int (lua_toboolean) (lua_State *L, int idx); |
| 182 | 172 | LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); |
| 183 | 173 | LUA_API size_t (lua_rawlen) (lua_State *L, int idx); |
| r242899 | r242900 | |
| 191 | 181 | ** Comparison and arithmetic functions |
| 192 | 182 | */ |
| 193 | 183 | |
| 194 | #define LUA_OPADD 0 /* ORDER TM | |
| 184 | #define LUA_OPADD 0 /* ORDER TM */ | |
| 195 | 185 | #define LUA_OPSUB 1 |
| 196 | 186 | #define LUA_OPMUL 2 |
| 197 | #define LUA_OPMOD 3 | |
| 198 | #define LUA_OPPOW 4 | |
| 199 | #define LUA_OPDIV 5 | |
| 200 | #define LUA_OPIDIV 6 | |
| 201 | #define LUA_OPBAND 7 | |
| 202 | #define LUA_OPBOR 8 | |
| 203 | #define LUA_OPBXOR 9 | |
| 204 | #define LUA_OPSHL 10 | |
| 205 | #define LUA_OPSHR 11 | |
| 206 | #define LUA_OPUNM 12 | |
| 207 | #define LUA_OPBNOT 13 | |
| 187 | #define LUA_OPDIV 3 | |
| 188 | #define LUA_OPMOD 4 | |
| 189 | #define LUA_OPPOW 5 | |
| 190 | #define LUA_OPUNM 6 | |
| 208 | 191 | |
| 209 | 192 | LUA_API void (lua_arith) (lua_State *L, int op); |
| 210 | 193 | |
| r242899 | r242900 | |
| 222 | 205 | LUA_API void (lua_pushnil) (lua_State *L); |
| 223 | 206 | LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); |
| 224 | 207 | LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); |
| 225 | LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len); | |
| 208 | LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n); | |
| 209 | LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l); | |
| 226 | 210 | LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); |
| 227 | 211 | LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, |
| 228 | 212 | va_list argp); |
| r242899 | r242900 | |
| 236 | 220 | /* |
| 237 | 221 | ** get functions (Lua -> stack) |
| 238 | 222 | */ |
| 239 | LUA_API int (lua_getglobal) (lua_State *L, const char *name); | |
| 240 | LUA_API int (lua_gettable) (lua_State *L, int idx); | |
| 241 | LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k); | |
| 242 | LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n); | |
| 243 | LUA_API int (lua_rawget) (lua_State *L, int idx); | |
| 244 | LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); | |
| 245 | LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); | |
| 246 | ||
| 223 | LUA_API void (lua_getglobal) (lua_State *L, const char *var); | |
| 224 | LUA_API void (lua_gettable) (lua_State *L, int idx); | |
| 225 | LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); | |
| 226 | LUA_API void (lua_rawget) (lua_State *L, int idx); | |
| 227 | LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); | |
| 228 | LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p); | |
| 247 | 229 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); |
| 248 | 230 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); |
| 249 | 231 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); |
| 250 | LUA_API i | |
| 232 | LUA_API void (lua_getuservalue) (lua_State *L, int idx); | |
| 251 | 233 | |
| 252 | 234 | |
| 253 | 235 | /* |
| 254 | 236 | ** set functions (stack -> Lua) |
| 255 | 237 | */ |
| 256 | LUA_API void (lua_setglobal) (lua_State *L, const char * | |
| 238 | LUA_API void (lua_setglobal) (lua_State *L, const char *var); | |
| 257 | 239 | LUA_API void (lua_settable) (lua_State *L, int idx); |
| 258 | 240 | LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); |
| 259 | LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n); | |
| 260 | 241 | LUA_API void (lua_rawset) (lua_State *L, int idx); |
| 261 | LUA_API void (lua_rawseti) (lua_State *L, int idx, | |
| 242 | LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); | |
| 262 | 243 | LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); |
| 263 | 244 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); |
| 264 | 245 | LUA_API void (lua_setuservalue) (lua_State *L, int idx); |
| r242899 | r242900 | |
| 267 | 248 | /* |
| 268 | 249 | ** 'load' and 'call' functions (load and run Lua code) |
| 269 | 250 | */ |
| 270 | LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, | |
| 271 | lua_KContext ctx, lua_KFunction k); | |
| 251 | LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx, | |
| 252 | lua_CFunction k); | |
| 272 | 253 | #define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) |
| 273 | 254 | |
| 255 | LUA_API int (lua_getctx) (lua_State *L, int *ctx); | |
| 256 | ||
| 274 | 257 | LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, |
| 275 | | |
| 258 | int ctx, lua_CFunction k); | |
| 276 | 259 | #define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) |
| 277 | 260 | |
| 278 | 261 | LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, |
| 279 | const char *chunkname, const char *mode); | |
| 262 | const char *chunkname, | |
| 263 | const char *mode); | |
| 280 | 264 | |
| 281 | LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data | |
| 265 | LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); | |
| 282 | 266 | |
| 283 | 267 | |
| 284 | 268 | /* |
| 285 | 269 | ** coroutine functions |
| 286 | 270 | */ |
| 287 | LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, | |
| 288 | lua_KFunction k); | |
| 289 | LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); | |
| 290 | LUA_API int (lua_status) (lua_State *L); | |
| 291 | LUA_API int (lua_isyieldable) (lua_State *L); | |
| 292 | ||
| 271 | LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx, | |
| 272 | lua_CFunction k); | |
| 293 | 273 | #define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) |
| 274 | LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); | |
| 275 | LUA_API int (lua_status) (lua_State *L); | |
| 294 | 276 | |
| 295 | ||
| 296 | 277 | /* |
| 297 | 278 | ** garbage-collection function and options |
| 298 | 279 | */ |
| r242899 | r242900 | |
| 305 | 286 | #define LUA_GCSTEP 5 |
| 306 | 287 | #define LUA_GCSETPAUSE 6 |
| 307 | 288 | #define LUA_GCSETSTEPMUL 7 |
| 289 | #define LUA_GCSETMAJORINC 8 | |
| 308 | 290 | #define LUA_GCISRUNNING 9 |
| 291 | #define LUA_GCGEN 10 | |
| 292 | #define LUA_GCINC 11 | |
| 309 | 293 | |
| 310 | 294 | LUA_API int (lua_gc) (lua_State *L, int what, int data); |
| 311 | 295 | |
| r242899 | r242900 | |
| 321 | 305 | LUA_API void (lua_concat) (lua_State *L, int n); |
| 322 | 306 | LUA_API void (lua_len) (lua_State *L, int idx); |
| 323 | 307 | |
| 324 | LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); | |
| 325 | ||
| 326 | 308 | LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); |
| 327 | 309 | LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); |
| 328 | 310 | |
| 329 | 311 | |
| 330 | 312 | |
| 331 | 313 | /* |
| 332 | ** | |
| 314 | ** =============================================================== | |
| 333 | 315 | ** some useful macros |
| 334 | 316 | ** =============================================================== |
| 335 | 317 | */ |
| 336 | 318 | |
| 337 | #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE)) | |
| 319 | #define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) | |
| 320 | #define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) | |
| 321 | #define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) | |
| 338 | 322 | |
| 339 | #define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL) | |
| 340 | #define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL) | |
| 341 | ||
| 342 | 323 | #define lua_pop(L,n) lua_settop(L, -(n)-1) |
| 343 | 324 | |
| 344 | 325 | #define lua_newtable(L) lua_createtable(L, 0, 0) |
| r242899 | r242900 | |
| 365 | 346 | #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) |
| 366 | 347 | |
| 367 | 348 | |
| 368 | #define lua_insert(L,idx) lua_rotate(L, (idx), 1) | |
| 369 | 349 | |
| 370 | #define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) | |
| 371 | ||
| 372 | #define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) | |
| 373 | ||
| 374 | /* }============================================================== */ | |
| 375 | ||
| 376 | ||
| 377 | 350 | /* |
| 378 | ** {============================================================== | |
| 379 | ** compatibility macros for unsigned conversions | |
| 380 | ** =============================================================== | |
| 381 | */ | |
| 382 | #if defined(LUA_COMPAT_APIINTCASTS) | |
| 383 | ||
| 384 | #define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) | |
| 385 | #define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is)) | |
| 386 | #define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) | |
| 387 | ||
| 388 | #endif | |
| 389 | /* }============================================================== */ | |
| 390 | ||
| 391 | /* | |
| 392 | 351 | ** {====================================================================== |
| 393 | 352 | ** Debug API |
| 394 | 353 | ** ======================================================================= |
| r242899 | r242900 | |
| 431 | 390 | LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, |
| 432 | 391 | int fidx2, int n2); |
| 433 | 392 | |
| 434 | LUA_API | |
| 393 | LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); | |
| 435 | 394 | LUA_API lua_Hook (lua_gethook) (lua_State *L); |
| 436 | 395 | LUA_API int (lua_gethookmask) (lua_State *L); |
| 437 | 396 | LUA_API int (lua_gethookcount) (lua_State *L); |
| r242899 | r242900 | |
| 459 | 418 | |
| 460 | 419 | |
| 461 | 420 | /****************************************************************************** |
| 462 | * Copyright (C) 1994-201 | |
| 421 | * Copyright (C) 1994-2013 Lua.org, PUC-Rio. | |
| 463 | 422 | * |
| 464 | 423 | * Permission is hereby granted, free of charge, to any person obtaining |
| 465 | 424 | * a copy of this software and associated documentation files (the |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: luac.c,v 1.72 2015/01/06 03:09:13 lhf Exp $ | |
| 3 | ** Lua compiler (saves bytecodes to files; also lists bytecodes) | |
| 2 | ** $Id: luac.c,v 1.69 2011/11/29 17:46:33 lhf Exp $ | |
| 3 | ** Lua compiler (saves bytecodes to files; also list bytecodes) | |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define luac_c | |
| 8 | #define LUA_CORE | |
| 9 | ||
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | #include <ctype.h> | |
| 13 | 7 | #include <errno.h> |
| 14 | 8 | #include <stdio.h> |
| 15 | 9 | #include <stdlib.h> |
| 16 | 10 | #include <string.h> |
| 17 | 11 | |
| 12 | #define luac_c | |
| 13 | #define LUA_CORE | |
| 14 | ||
| 18 | 15 | #include "lua.h" |
| 19 | 16 | #include "lauxlib.h" |
| 20 | 17 | |
| r242899 | r242900 | |
| 50 | 47 | static void usage(const char* message) |
| 51 | 48 | { |
| 52 | 49 | if (*message=='-') |
| 53 | fprintf(stderr,"%s: unrecognized option | |
| 50 | fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); | |
| 54 | 51 | else |
| 55 | 52 | fprintf(stderr,"%s: %s\n",progname,message); |
| 56 | 53 | fprintf(stderr, |
| 57 | 54 | "usage: %s [options] [filenames]\n" |
| 58 | 55 | "Available options are:\n" |
| 59 | 56 | " -l list (use -l -l for full listing)\n" |
| 60 | " -o name output to file | |
| 57 | " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" | |
| 61 | 58 | " -p parse only\n" |
| 62 | 59 | " -s strip debug information\n" |
| 63 | 60 | " -v show version information\n" |
| r242899 | r242900 | |
| 92 | 89 | { |
| 93 | 90 | output=argv[++i]; |
| 94 | 91 | if (output==NULL || *output==0 || (*output=='-' && output[1]!=0)) |
| 95 | usage(" | |
| 92 | usage(LUA_QL("-o") " needs argument"); | |
| 96 | 93 | if (IS("-")) output=NULL; |
| 97 | 94 | } |
| 98 | 95 | else if (IS("-p")) /* parse only */ |
| r242899 | r242900 | |
| 206 | 203 | } |
| 207 | 204 | |
| 208 | 205 | /* |
| 209 | ** $Id: print.c,v 1. | |
| 206 | ** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $ | |
| 210 | 207 | ** print bytecodes |
| 211 | 208 | ** See Copyright Notice in lua.h |
| 212 | 209 | */ |
| r242899 | r242900 | |
| 226 | 223 | static void PrintString(const TString* ts) |
| 227 | 224 | { |
| 228 | 225 | const char* s=getstr(ts); |
| 229 | size_t i,n=ts->len; | |
| 226 | size_t i,n=ts->tsv.len; | |
| 230 | 227 | printf("%c",'"'); |
| 231 | 228 | for (i=0; i<n; i++) |
| 232 | 229 | { |
| r242899 | r242900 | |
| 254 | 251 | static void PrintConstant(const Proto* f, int i) |
| 255 | 252 | { |
| 256 | 253 | const TValue* o=&f->k[i]; |
| 257 | switch (ttype(o)) | |
| 254 | switch (ttypenv(o)) | |
| 258 | 255 | { |
| 259 | 256 | case LUA_TNIL: |
| 260 | 257 | printf("nil"); |
| r242899 | r242900 | |
| 262 | 259 | case LUA_TBOOLEAN: |
| 263 | 260 | printf(bvalue(o) ? "true" : "false"); |
| 264 | 261 | break; |
| 265 | case LUA_TNUMFLT: | |
| 266 | { | |
| 267 | char buff[100]; | |
| 268 | sprintf(buff,LUA_NUMBER_FMT,fltvalue(o)); | |
| 269 | printf("%s",buff); | |
| 270 | if (buff[strspn(buff,"-0123456789")]=='\0') printf(".0"); | |
| 262 | case LUA_TNUMBER: | |
| 263 | printf(LUA_NUMBER_FMT,nvalue(o)); | |
| 271 | 264 | break; |
| 272 | } | |
| 273 | case LUA_TNUMINT: | |
| 274 | printf(LUA_INTEGER_FMT,ivalue(o)); | |
| 265 | case LUA_TSTRING: | |
| 266 | PrintString(rawtsvalue(o)); | |
| 275 | 267 | break; |
| 276 | case LUA_TSHRSTR: case LUA_TLNGSTR: | |
| 277 | PrintString(tsvalue(o)); | |
| 278 | break; | |
| 279 | 268 | default: /* cannot happen */ |
| 280 | 269 | printf("? type=%d",ttype(o)); |
| 281 | 270 | break; |
| r242899 | r242900 | |
| 348 | 337 | case OP_ADD: |
| 349 | 338 | case OP_SUB: |
| 350 | 339 | case OP_MUL: |
| 351 | case OP_POW: | |
| 352 | 340 | case OP_DIV: |
| 353 | case OP_IDIV: | |
| 354 | case OP_BAND: | |
| 355 | case OP_BOR: | |
| 356 | case OP_BXOR: | |
| 357 | case OP_SHL: | |
| 358 | case OP_SHR: | |
| 341 | case OP_POW: | |
| 359 | 342 | case OP_EQ: |
| 360 | 343 | case OP_LT: |
| 361 | 344 | case OP_LE: |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: luaconf.h,v 1. | |
| 2 | ** $Id: luaconf.h,v 1.176.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Configuration file for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | #ifndef luaconf_h | |
| 9 | #define luaconf_h | |
| 8 | #ifndef lconfig_h | |
| 9 | #define lconfig_h | |
| 10 | 10 | |
| 11 | 11 | #include <limits.h> |
| 12 | 12 | #include <stddef.h> |
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | /* |
| 16 | ** ================================================================== | |
| 16 | ** ================================================================== | |
| 17 | 17 | ** Search for "@@" to find all configurable definitions. |
| 18 | 18 | ** =================================================================== |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | 21 | |
| 22 | 22 | /* |
| 23 | ** {==================================================================== | |
| 24 | ** System Configuration: macros to adapt (if needed) Lua to some | |
| 25 | ** particular platform, for instance compiling it with 32-bit numbers or | |
| 26 | ** restricting it to C89. | |
| 27 | ** ===================================================================== | |
| 23 | @@ LUA_ANSI controls the use of non-ansi features. | |
| 24 | ** CHANGE it (define it) if you want Lua to avoid the use of any | |
| 25 | ** non-ansi feature or library. | |
| 28 | 26 | */ |
| 27 | #if !defined(LUA_ANSI) && defined(__STRICT_ANSI__) | |
| 28 | #define LUA_ANSI | |
| 29 | #endif | |
| 29 | 30 | |
| 30 | /* | |
| 31 | @@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You | |
| 32 | ** can also define LUA_32BITS in the make file, but changing here you | |
| 33 | ** ensure that all software connected to Lua will be compiled with the | |
| 34 | ** same configuration. | |
| 35 | */ | |
| 36 | /* #define LUA_32BITS */ | |
| 37 | 31 | |
| 38 | ||
| 39 | /* | |
| 40 | @@ LUA_USE_C89 controls the use of non-ISO-C89 features. | |
| 41 | ** Define it if you want Lua to avoid the use of a few C99 features | |
| 42 | ** or Windows-specific features on Windows. | |
| 43 | */ | |
| 44 | /* #define LUA_USE_C89 */ | |
| 45 | ||
| 46 | ||
| 47 | /* | |
| 48 | ** By default, Lua on Windows use (some) specific Windows features | |
| 49 | */ | |
| 50 | #if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE) | |
| 51 | #define LUA_USE_WINDOWS /* enable goodies for regular Windows */ | |
| 32 | #if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE) | |
| 33 | #define LUA_WIN /* enable goodies for regular Windows platforms */ | |
| 52 | 34 | #endif |
| 53 | 35 | |
| 54 | ||
| 55 | #if defined(LUA_USE_WINDOWS) | |
| 56 | #define LUA_DL_DLL /* enable support for DLL */ | |
| 57 | #define LUA_USE_C89 /* broadly, Windows is C89 */ | |
| 36 | #if defined(LUA_WIN) | |
| 37 | #define LUA_DL_DLL | |
| 38 | #define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ | |
| 58 | 39 | #endif |
| 59 | 40 | |
| 60 | 41 | |
| 42 | ||
| 61 | 43 | #if defined(LUA_USE_LINUX) |
| 62 | 44 | #define LUA_USE_POSIX |
| 63 | 45 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ |
| 64 | 46 | #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 */ | |
| 65 | 50 | #endif |
| 66 | 51 | |
| 67 | ||
| 68 | 52 | #if defined(LUA_USE_MACOSX) |
| 69 | 53 | #define LUA_USE_POSIX |
| 70 | #define LUA_USE_DLOPEN /* | |
| 54 | #define LUA_USE_DLOPEN /* does not need -ldl */ | |
| 71 | 55 | #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 */ | |
| 72 | 59 | #endif |
| 73 | 60 | |
| 74 | 61 | |
| 75 | /* | |
| 76 | @@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for | |
| 77 | ** C89 ('long' and 'double'); Windows always has '__int64', so it does | |
| 78 | ** not need to use this case. | |
| 79 | */ | |
| 80 | #if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) | |
| 81 | #define LUA_C89_NUMBERS | |
| 82 | #endif | |
| 83 | 62 | |
| 84 | ||
| 85 | ||
| 86 | 63 | /* |
| 87 | @@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'. | |
| 64 | @@ LUA_USE_POSIX includes all functionality listed as X/Open System | |
| 65 | @* Interfaces Extension (XSI). | |
| 66 | ** CHANGE it (define it) if your system is XSI compatible. | |
| 88 | 67 | */ |
| 89 | /* avoid undefined shifts */ | |
| 90 | #if ((INT_MAX >> 15) >> 15) >= 1 | |
| 91 | #define LUAI_BITSINT 32 | |
| 92 | #else | |
| 93 | /* 'int' always must have at least 16 bits */ | |
| 94 | #define LUAI_BITSINT 16 | |
| 68 | #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 | |
| 95 | 74 | #endif |
| 96 | 75 | |
| 97 | 76 | |
| 98 | /* | |
| 99 | @@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines the type for | |
| 100 | ** Lua integers. | |
| 101 | @@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines | |
| 102 | ** the type for Lua floats. | |
| 103 | ** Lua should work fine with any mix of these options (if supported | |
| 104 | ** by your C compiler). The usual configurations are 64-bit integers | |
| 105 | ** and 'double' (the default), 32-bit integers and 'float' (for | |
| 106 | ** restricted platforms), and 'long'/'double' (for C compilers not | |
| 107 | ** compliant with C99, which may not have support for 'long long'). | |
| 108 | */ | |
| 109 | 77 | |
| 110 | #if defined(LUA_32BITS) /* { */ | |
| 111 | 78 | /* |
| 112 | ** 32-bit integers and 'float' | |
| 113 | */ | |
| 114 | #if LUAI_BITSINT >= 32 /* use 'int' if big enough */ | |
| 115 | #define LUA_INT_INT | |
| 116 | #else /* otherwise use 'long' */ | |
| 117 | #define LUA_INT_LONG | |
| 118 | #endif | |
| 119 | #define LUA_REAL_FLOAT | |
| 120 | ||
| 121 | #elif defined(LUA_C89_NUMBERS) /* }{ */ | |
| 122 | /* | |
| 123 | ** largest types available for C89 ('long' and 'double') | |
| 124 | */ | |
| 125 | #define LUA_INT_LONG | |
| 126 | #define LUA_REAL_DOUBLE | |
| 127 | ||
| 128 | #else /* }{ */ | |
| 129 | /* | |
| 130 | ** default configuration for 64-bit Lua ('long long' and 'double') | |
| 131 | */ | |
| 132 | #define LUA_INT_LONGLONG | |
| 133 | #define LUA_REAL_DOUBLE | |
| 134 | ||
| 135 | #endif /* } */ | |
| 136 | ||
| 137 | /* }================================================================== */ | |
| 138 | ||
| 139 | ||
| 140 | ||
| 141 | ||
| 142 | /* | |
| 143 | ** {================================================================== | |
| 144 | ** Configuration for Paths. | |
| 145 | ** =================================================================== | |
| 146 | */ | |
| 147 | ||
| 148 | /* | |
| 149 | 79 | @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for |
| 150 | ||
| 80 | @* Lua libraries. | |
| 151 | 81 | @@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for |
| 152 | ||
| 82 | @* C libraries. | |
| 153 | 83 | ** CHANGE them if your machine has a non-conventional directory |
| 154 | 84 | ** hierarchy or if you want to install your libraries in |
| 155 | 85 | ** non-conventional directories. |
| 156 | 86 | */ |
| 157 | #define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR | |
| 158 | #if defined(_WIN32) /* { */ | |
| 87 | #if defined(_WIN32) /* { */ | |
| 159 | 88 | /* |
| 160 | 89 | ** In Windows, any exclamation mark ('!') in the path is replaced by the |
| 161 | 90 | ** path of the directory of the executable file of the current process. |
| 162 | 91 | */ |
| 163 | 92 | #define LUA_LDIR "!\\lua\\" |
| 164 | 93 | #define LUA_CDIR "!\\" |
| 165 | #define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" | |
| 166 | 94 | #define LUA_PATH_DEFAULT \ |
| 167 | 95 | LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ |
| 168 | LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ | |
| 169 | LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ | |
| 170 | ".\\?.lua;" ".\\?\\init.lua" | |
| 96 | LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua" | |
| 171 | 97 | #define LUA_CPATH_DEFAULT \ |
| 172 | LUA_CDIR"?.dll;" \ | |
| 173 | LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ | |
| 174 | LUA_CDIR"loadall.dll;" ".\\?.dll" | |
| 98 | LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" | |
| 175 | 99 | |
| 176 | 100 | #else /* }{ */ |
| 177 | 101 | |
| 102 | #define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/" | |
| 178 | 103 | #define LUA_ROOT "/usr/local/" |
| 179 | #define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" | |
| 180 | #define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" | |
| 104 | #define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR | |
| 105 | #define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR | |
| 181 | 106 | #define LUA_PATH_DEFAULT \ |
| 182 | 107 | LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ |
| 183 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ | |
| 184 | "./?.lua;" "./?/init.lua" | |
| 108 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" | |
| 185 | 109 | #define LUA_CPATH_DEFAULT \ |
| 186 | 110 | LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" |
| 187 | 111 | #endif /* } */ |
| r242899 | r242900 | |
| 198 | 122 | #define LUA_DIRSEP "/" |
| 199 | 123 | #endif |
| 200 | 124 | |
| 201 | /* }================================================================== */ | |
| 202 | 125 | |
| 203 | ||
| 204 | 126 | /* |
| 205 | ** {================================================================== | |
| 206 | ** Marks for exported symbols in the C code | |
| 207 | ** =================================================================== | |
| 127 | @@ LUA_ENV is the name of the variable that holds the current | |
| 128 | @@ environment, used to access global names. | |
| 129 | ** CHANGE it if you do not like this name. | |
| 208 | 130 | */ |
| 131 | #define LUA_ENV "_ENV" | |
| 209 | 132 | |
| 133 | ||
| 210 | 134 | /* |
| 211 | 135 | @@ LUA_API is a mark for all core API functions. |
| 212 | 136 | @@ LUALIB_API is a mark for all auxiliary library functions. |
| r242899 | r242900 | |
| 238 | 162 | |
| 239 | 163 | /* |
| 240 | 164 | @@ LUAI_FUNC is a mark for all extern functions that are not to be |
| 241 | ||
| 165 | @* exported to outside modules. | |
| 242 | 166 | @@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables |
| 243 | ** that are not to be exported to outside modules (LUAI_DDEF for | |
| 244 | ** definitions and LUAI_DDEC for declarations). | |
| 167 | @* that are not to be exported to outside modules (LUAI_DDEF for | |
| 168 | @* definitions and LUAI_DDEC for declarations). | |
| 245 | 169 | ** CHANGE them if you need to mark them in some special way. Elf/gcc |
| 246 | 170 | ** (versions 3.2 and later) mark them as "hidden" to optimize access |
| 247 | 171 | ** when Lua is compiled as a shared library. Not all elf targets support |
| r242899 | r242900 | |
| 253 | 177 | #if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ |
| 254 | 178 | defined(__ELF__) /* { */ |
| 255 | 179 | #define LUAI_FUNC __attribute__((visibility("hidden"))) extern |
| 180 | #define LUAI_DDEC LUAI_FUNC | |
| 181 | #define LUAI_DDEF /* empty */ | |
| 182 | ||
| 256 | 183 | #else /* }{ */ |
| 257 | 184 | #define LUAI_FUNC extern |
| 185 | #define LUAI_DDEC extern | |
| 186 | #define LUAI_DDEF /* empty */ | |
| 258 | 187 | #endif /* } */ |
| 259 | 188 | |
| 260 | #define LUAI_DDEC LUAI_FUNC | |
| 261 | #define LUAI_DDEF /* empty */ | |
| 262 | 189 | |
| 263 | /* }================================================================== */ | |
| 264 | 190 | |
| 265 | ||
| 266 | 191 | /* |
| 267 | ** {================================================================== | |
| 268 | ** Compatibility with previous versions | |
| 269 | ** =================================================================== | |
| 192 | @@ LUA_QL describes how error messages quote program elements. | |
| 193 | ** CHANGE it if you want a different appearance. | |
| 270 | 194 | */ |
| 195 | #define LUA_QL(x) "'" x "'" | |
| 196 | #define LUA_QS LUA_QL("%s") | |
| 271 | 197 | |
| 272 | /* | |
| 273 | @@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2. | |
| 274 | @@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1. | |
| 275 | ** You can define it to get all options, or change specific options | |
| 276 | ** to fit your specific needs. | |
| 277 | */ | |
| 278 | #if defined(LUA_COMPAT_5_2) /* { */ | |
| 279 | 198 | |
| 280 | 199 | /* |
| 281 | @@ LUA_COMPAT_MATHLIB controls the presence of several deprecated | |
| 282 | ** functions in the mathematical library. | |
| 200 | @@ LUA_IDSIZE gives the maximum size for the description of the source | |
| 201 | @* of a function in debug information. | |
| 202 | ** CHANGE it if you want a different size. | |
| 283 | 203 | */ |
| 284 | #define LUA_ | |
| 204 | #define LUA_IDSIZE 60 | |
| 285 | 205 | |
| 286 | /* | |
| 287 | @@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'. | |
| 288 | */ | |
| 289 | #define LUA_COMPAT_BITLIB | |
| 290 | 206 | |
| 291 | 207 | /* |
| 292 | @@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod. | |
| 208 | @@ luai_writestring/luai_writeline define how 'print' prints its results. | |
| 209 | ** They are only used in libraries and the stand-alone program. (The #if | |
| 210 | ** avoids including 'stdio.h' everywhere.) | |
| 293 | 211 | */ |
| 294 | #define LUA_COMPAT_IPAIRS | |
| 212 | #if defined(LUA_LIB) || defined(lua_c) | |
| 213 | #include <stdio.h> | |
| 214 | #define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) | |
| 215 | #define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) | |
| 216 | #endif | |
| 295 | 217 | |
| 296 | 218 | /* |
| 297 | @@ LUA_COMPAT_APIINTCASTS controls the presence of macros for | |
| 298 | ** manipulating other integer types (lua_pushunsigned, lua_tounsigned, | |
| 299 | ** luaL_checkint, luaL_checklong, etc.) | |
| 219 | @@ luai_writestringerror defines how to print error messages. | |
| 220 | ** (A format string with one argument is enough for Lua...) | |
| 300 | 221 | */ |
| 301 | #define LUA_COMPAT_APIINTCASTS | |
| 222 | #define luai_writestringerror(s,p) \ | |
| 223 | (fprintf(stderr, (s), (p)), fflush(stderr)) | |
| 302 | 224 | |
| 303 | 225 | |
| 304 | 226 | /* |
| 305 | @@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a | |
| 306 | @@ a float mark ('.0'). | |
| 307 | ** This macro is not on by default even in compatibility mode, | |
| 308 | ** because this is not really an incompatibility. | |
| 227 | @@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is, | |
| 228 | ** strings that are internalized. (Cannot be smaller than reserved words | |
| 229 | ** or tags for metamethods, as these strings must be internalized; | |
| 230 | ** #("function") = 8, #("__newindex") = 10.) | |
| 309 | 231 | */ |
| 310 | ||
| 232 | #define LUAI_MAXSHORTLEN 40 | |
| 311 | 233 | |
| 312 | #endif /* } */ | |
| 313 | 234 | |
| 314 | 235 | |
| 315 | #if defined(LUA_COMPAT_5_1) /* { */ | |
| 236 | /* | |
| 237 | ** {================================================================== | |
| 238 | ** Compatibility with previous versions | |
| 239 | ** =================================================================== | |
| 240 | */ | |
| 316 | 241 | |
| 317 | 242 | /* |
| 243 | @@ LUA_COMPAT_ALL controls all compatibility options. | |
| 244 | ** You can define it to get all options, or change specific options | |
| 245 | ** to fit your specific needs. | |
| 246 | */ | |
| 247 | #if defined(LUA_COMPAT_ALL) /* { */ | |
| 248 | ||
| 249 | /* | |
| 318 | 250 | @@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. |
| 319 | 251 | ** You can replace it with 'table.unpack'. |
| 320 | 252 | */ |
| r242899 | r242900 | |
| 378 | 310 | |
| 379 | 311 | |
| 380 | 312 | /* |
| 381 | ** {================================================================== | |
| 382 | ** Configuration for Numbers. | |
| 383 | ** Change these definitions if no predefined LUA_REAL_* / LUA_INT_* | |
| 384 | ** satisfy your needs. | |
| 385 | ** =================================================================== | |
| 313 | @@ LUAI_BITSINT defines the number of bits in an int. | |
| 314 | ** CHANGE here if Lua cannot automatically detect the number of bits of | |
| 315 | ** your machine. Probably you do not need to change this. | |
| 386 | 316 | */ |
| 317 | /* avoid overflows in comparison */ | |
| 318 | #if INT_MAX-20 < 32760 /* { */ | |
| 319 | #define LUAI_BITSINT 16 | |
| 320 | #elif INT_MAX > 2147483640L /* }{ */ | |
| 321 | /* int has at least 32 bits */ | |
| 322 | #define LUAI_BITSINT 32 | |
| 323 | #else /* }{ */ | |
| 324 | #error "you must define LUA_BITSINT with number of bits in an integer" | |
| 325 | #endif /* } */ | |
| 387 | 326 | |
| 327 | ||
| 388 | 328 | /* |
| 389 | @@ LUA_NUMBER is the floating-point type used by Lua. | |
| 390 | ** | |
| 391 | @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' | |
| 392 | @@ over a floating number. | |
| 393 | ** | |
| 394 | @@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. | |
| 395 | @@ LUA_NUMBER_FMT is the format for writing floats. | |
| 396 | @@ lua_number2str converts a float to a string. | |
| 397 | ** | |
| 398 | @@ l_mathop allows the addition of an 'l' or 'f' to all math operations. | |
| 399 | ** | |
| 400 | @@ lua_str2number converts a decimal numeric string to a number. | |
| 329 | @@ LUA_INT32 is an signed integer with exactly 32 bits. | |
| 330 | @@ LUAI_UMEM is an unsigned integer big enough to count the total | |
| 331 | @* memory used by Lua. | |
| 332 | @@ LUAI_MEM is a signed integer big enough to count the total memory | |
| 333 | @* used by Lua. | |
| 334 | ** CHANGE here if for some weird reason the default definitions are not | |
| 335 | ** good enough for your machine. Probably you do not need to change | |
| 336 | ** this. | |
| 401 | 337 | */ |
| 338 | #if LUAI_BITSINT >= 32 /* { */ | |
| 339 | #define LUA_INT32 int | |
| 340 | #define LUAI_UMEM size_t | |
| 341 | #define LUAI_MEM ptrdiff_t | |
| 342 | #else /* }{ */ | |
| 343 | /* 16-bit ints */ | |
| 344 | #define LUA_INT32 long | |
| 345 | #define LUAI_UMEM unsigned long | |
| 346 | #define LUAI_MEM long | |
| 347 | #endif /* } */ | |
| 402 | 348 | |
| 403 | #if defined(LUA_REAL_FLOAT) /* { single float */ | |
| 404 | 349 | |
| 405 | #define LUA_NUMBER float | |
| 350 | /* | |
| 351 | @@ LUAI_MAXSTACK limits the size of the Lua stack. | |
| 352 | ** CHANGE it if you need a different limit. This limit is arbitrary; | |
| 353 | ** its only purpose is to stop Lua to consume unlimited stack | |
| 354 | ** space (and to reserve some numbers for pseudo-indices). | |
| 355 | */ | |
| 356 | #if LUAI_BITSINT >= 32 | |
| 357 | #define LUAI_MAXSTACK 1000000 | |
| 358 | #else | |
| 359 | #define LUAI_MAXSTACK 15000 | |
| 360 | #endif | |
| 406 | 361 | |
| 407 | #define LUAI_UACNUMBER double | |
| 362 | /* reserve some space for error handling */ | |
| 363 | #define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) | |
| 408 | 364 | |
| 409 | #define LUA_NUMBER_FRMLEN "" | |
| 410 | #define LUA_NUMBER_FMT "%.7g" | |
| 411 | 365 | |
| 412 | #define l_mathop(op) op##f | |
| 413 | 366 | |
| 414 | #define lua_str2number(s,p) strtof((s), (p)) | |
| 415 | 367 | |
| 368 | /* | |
| 369 | @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. | |
| 370 | ** CHANGE it if it uses too much C-stack space. | |
| 371 | */ | |
| 372 | #define LUAL_BUFFERSIZE BUFSIZ | |
| 416 | 373 | |
| 417 | #elif defined(LUA_REAL_LONGDOUBLE) /* }{ long double */ | |
| 418 | 374 | |
| 419 | #define LUA_NUMBER long double | |
| 420 | 375 | |
| 421 | #define LUAI_UACNUMBER long double | |
| 422 | 376 | |
| 423 | #define LUA_NUMBER_FRMLEN "L" | |
| 424 | #define LUA_NUMBER_FMT "%.19Lg" | |
| 377 | /* | |
| 378 | ** {================================================================== | |
| 379 | @@ LUA_NUMBER is the type of numbers in Lua. | |
| 380 | ** CHANGE the following definitions only if you want to build Lua | |
| 381 | ** with a number type different from double. You may also need to | |
| 382 | ** change lua_number2int & lua_number2integer. | |
| 383 | ** =================================================================== | |
| 384 | */ | |
| 425 | 385 | |
| 426 | #define l_mathop(op) op##l | |
| 427 | ||
| 428 | #define lua_str2number(s,p) strtold((s), (p)) | |
| 429 | ||
| 430 | #elif defined(LUA_REAL_DOUBLE) /* }{ double */ | |
| 431 | ||
| 386 | #define LUA_NUMBER_DOUBLE | |
| 432 | 387 | #define LUA_NUMBER double |
| 433 | 388 | |
| 389 | /* | |
| 390 | @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' | |
| 391 | @* over a number. | |
| 392 | */ | |
| 434 | 393 | #define LUAI_UACNUMBER double |
| 435 | 394 | |
| 436 | #define LUA_NUMBER_FRMLEN "" | |
| 437 | #define LUA_NUMBER_FMT "%.14g" | |
| 438 | 395 | |
| 439 | #define l_mathop(op) op | |
| 440 | ||
| 441 | #define lua_str2number(s,p) strtod((s), (p)) | |
| 442 | ||
| 443 | #else /* }{ */ | |
| 444 | ||
| 445 | #error "numeric real type not defined" | |
| 446 | ||
| 447 | #endif /* } */ | |
| 448 | ||
| 449 | ||
| 450 | #define l_floor(x) (l_mathop(floor)(x)) | |
| 451 | ||
| 396 | /* | |
| 397 | @@ LUA_NUMBER_SCAN is the format for reading numbers. | |
| 398 | @@ LUA_NUMBER_FMT is the format for writing numbers. | |
| 399 | @@ lua_number2str converts a number to a string. | |
| 400 | @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. | |
| 401 | */ | |
| 402 | #define LUA_NUMBER_SCAN "%lf" | |
| 403 | #define LUA_NUMBER_FMT "%.14g" | |
| 452 | 404 | #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) |
| 405 | #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ | |
| 453 | 406 | |
| 454 | 407 | |
| 455 | 408 | /* |
| 456 | @@ lua_numbertointeger converts a float number to an integer, or | |
| 457 | ** returns 0 if float is not within the range of a lua_Integer. | |
| 458 | ** (The range comparisons are tricky because of rounding. The tests | |
| 459 | ** here assume a two-complement representation, where MININTEGER always | |
| 460 | ** has an exact representation as a float; MAXINTEGER may not have one, | |
| 461 | ** and therefore its conversion to float may have an ill-defined value.) | |
| 409 | @@ l_mathop allows the addition of an 'l' or 'f' to all math operations | |
| 462 | 410 | */ |
| 463 | #define lua_numbertointeger(n,p) \ | |
| 464 | ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ | |
| 465 | (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ | |
| 466 | (*(p) = (LUA_INTEGER)(n), 1)) | |
| 411 | #define l_mathop(x) (x) | |
| 467 | 412 | |
| 468 | 413 | |
| 469 | 414 | /* |
| 470 | @@ The luai_num* macros define the primitive operations over numbers. | |
| 471 | ** They should work for any size of floating numbers. | |
| 415 | @@ lua_str2number converts a decimal numeric string to a number. | |
| 416 | @@ lua_strx2number converts an hexadecimal numeric string to a number. | |
| 417 | ** In C99, 'strtod' does both conversions. C89, however, has no function | |
| 418 | ** to convert floating hexadecimal strings to numbers. For these | |
| 419 | ** systems, you can leave 'lua_strx2number' undefined and Lua will | |
| 420 | ** provide its own implementation. | |
| 472 | 421 | */ |
| 422 | #define lua_str2number(s,p) strtod((s), (p)) | |
| 473 | 423 | |
| 474 | /* the following operations need the math library */ | |
| 475 | #if defined(lobject_c) || defined(lvm_c) | |
| 476 | #include <math.h> | |
| 424 | #if defined(LUA_USE_STRTODHEX) | |
| 425 | #define lua_strx2number(s,p) strtod((s), (p)) | |
| 426 | #endif | |
| 477 | 427 | |
| 478 | /* floor division (defined as 'floor(a/b)') */ | |
| 479 | #define luai_numidiv(L,a,b) ((void)L, l_mathop(floor)(luai_numdiv(L,a,b))) | |
| 480 | 428 | |
| 481 | 429 | /* |
| 482 | ** module: defined as 'a - floor(a/b)*b'; the previous definition gives | |
| 483 | ** NaN when 'b' is huge, but the result should be 'a'. 'fmod' gives the | |
| 484 | ** result of 'a - trunc(a/b)*b', and therefore must be corrected when | |
| 485 | ** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a | |
| 486 | ** non-integer negative result, which is equivalent to the test below | |
| 430 | @@ The luai_num* macros define the primitive operations over numbers. | |
| 487 | 431 | */ |
| 488 | #define luai_nummod(L,a,b,m) \ | |
| 489 | { (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); } | |
| 490 | 432 | |
| 491 | /* exponentiation */ | |
| 492 | #define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) | |
| 493 | ||
| 433 | /* the following operations need the math library */ | |
| 434 | #if defined(lobject_c) || defined(lvm_c) | |
| 435 | #include <math.h> | |
| 436 | #define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b)) | |
| 437 | #define luai_numpow(L,a,b) (l_mathop(pow)(a,b)) | |
| 494 | 438 | #endif |
| 495 | 439 | |
| 496 | 440 | /* these are quite standard operations */ |
| r242899 | r242900 | |
| 501 | 445 | #define luai_numdiv(L,a,b) ((a)/(b)) |
| 502 | 446 | #define luai_numunm(L,a) (-(a)) |
| 503 | 447 | #define luai_numeq(a,b) ((a)==(b)) |
| 504 | #define luai_numlt(a,b) ((a)<(b)) | |
| 505 | #define luai_numle(a,b) ((a)<=(b)) | |
| 506 | #define luai_numisnan(a) (!luai_numeq((a), (a))) | |
| 448 | #define luai_numlt(L,a,b) ((a)<(b)) | |
| 449 | #define luai_numle(L,a,b) ((a)<=(b)) | |
| 450 | #define luai_numisnan(L,a) (!luai_numeq((a), (a))) | |
| 507 | 451 | #endif |
| 508 | 452 | |
| 509 | 453 | |
| 510 | /* | |
| 511 | @@ LUA_INTEGER is the integer type used by Lua. | |
| 512 | ** | |
| 513 | @@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. | |
| 514 | ** | |
| 515 | @@ LUAI_UACINT is the result of an 'usual argument conversion' | |
| 516 | @@ over a lUA_INTEGER. | |
| 517 | @@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. | |
| 518 | @@ LUA_INTEGER_FMT is the format for writing integers. | |
| 519 | @@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. | |
| 520 | @@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. | |
| 521 | @@ lua_integer2str converts an integer to a string. | |
| 522 | */ | |
| 523 | 454 | |
| 524 | ||
| 525 | /* The following definitions are good for most cases here */ | |
| 526 | ||
| 527 | #define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" | |
| 528 | #define lua_integer2str(s,n) sprintf((s), LUA_INTEGER_FMT, (n)) | |
| 529 | ||
| 530 | #define LUAI_UACINT LUA_INTEGER | |
| 531 | ||
| 532 | 455 | /* |
| 533 | ** use LUAI_UACINT here to avoid problems with promotions (which | |
| 534 | ** can turn a comparison between unsigneds into a signed comparison) | |
| 456 | @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. | |
| 457 | ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most | |
| 458 | ** machines, ptrdiff_t gives a good choice between int or long.) | |
| 535 | 459 | */ |
| 536 | #define LUA_ | |
| 460 | #define LUA_INTEGER ptrdiff_t | |
| 537 | 461 | |
| 538 | ||
| 539 | /* now the variable definitions */ | |
| 540 | ||
| 541 | #if defined(LUA_INT_INT) /* { int */ | |
| 542 | ||
| 543 | #define LUA_INTEGER int | |
| 544 | #define LUA_INTEGER_FRMLEN "" | |
| 545 | ||
| 546 | #define LUA_MAXINTEGER INT_MAX | |
| 547 | #define LUA_MININTEGER INT_MIN | |
| 548 | ||
| 549 | #elif defined(LUA_INT_LONG) /* }{ long */ | |
| 550 | ||
| 551 | #define LUA_INTEGER long | |
| 552 | #define LUA_INTEGER_FRMLEN "l" | |
| 553 | ||
| 554 | #define LUA_MAXINTEGER LONG_MAX | |
| 555 | #define LUA_MININTEGER LONG_MIN | |
| 556 | ||
| 557 | #elif defined(LUA_INT_LONGLONG) /* }{ long long */ | |
| 558 | ||
| 559 | #if defined(LLONG_MAX) /* { */ | |
| 560 | /* use ISO C99 stuff */ | |
| 561 | ||
| 562 | #define LUA_INTEGER long long | |
| 563 | #define LUA_INTEGER_FRMLEN "ll" | |
| 564 | ||
| 565 | #define LUA_MAXINTEGER LLONG_MAX | |
| 566 | #define LUA_MININTEGER LLONG_MIN | |
| 567 | ||
| 568 | #elif defined(LUA_USE_WINDOWS) /* }{ */ | |
| 569 | /* in Windows, can use specific Windows types */ | |
| 570 | ||
| 571 | #define LUA_INTEGER __int64 | |
| 572 | #define LUA_INTEGER_FRMLEN "I64" | |
| 573 | ||
| 574 | #define LUA_MAXINTEGER _I64_MAX | |
| 575 | #define LUA_MININTEGER _I64_MIN | |
| 576 | ||
| 577 | #else /* }{ */ | |
| 578 | ||
| 579 | #error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ | |
| 580 | or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)" | |
| 581 | ||
| 582 | #endif /* } */ | |
| 583 | ||
| 584 | #else /* }{ */ | |
| 585 | ||
| 586 | #error "numeric integer type not defined" | |
| 587 | ||
| 588 | #endif /* } */ | |
| 589 | ||
| 590 | /* }================================================================== */ | |
| 591 | ||
| 592 | ||
| 593 | 462 | /* |
| 594 | ** {================================================================== | |
| 595 | ** Dependencies with C99 | |
| 596 | ** =================================================================== | |
| 463 | @@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. | |
| 464 | ** It must have at least 32 bits. | |
| 597 | 465 | */ |
| 466 | #define LUA_UNSIGNED unsigned LUA_INT32 | |
| 598 | 467 | |
| 599 | /* | |
| 600 | @@ lua_strx2number converts an hexadecimal numeric string to a number. | |
| 601 | ** In C99, 'strtod' does both conversions. Otherwise, you can | |
| 602 | ** leave 'lua_strx2number' undefined and Lua will provide its own | |
| 603 | ** implementation. | |
| 604 | */ | |
| 605 | #if !defined(LUA_USE_C89) | |
| 606 | #define lua_strx2number(s,p) lua_str2number(s,p) | |
| 607 | #endif | |
| 608 | 468 | |
| 609 | 469 | |
| 610 | 470 | /* |
| 611 | @@ LUA_USE_AFORMAT allows '%a'/'%A' specifiers in 'string.format' | |
| 612 | ** Enable it if the C function 'printf' supports these specifiers. | |
| 613 | ** (C99 demands it and Windows also supports it.) | |
| 471 | ** Some tricks with doubles | |
| 614 | 472 | */ |
| 615 | #if !defined(LUA_USE_C89) || defined(LUA_USE_WINDOWS) | |
| 616 | #define LUA_USE_AFORMAT | |
| 617 | #endif | |
| 618 | 473 | |
| 619 | ||
| 474 | #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ | |
| 620 | 475 | /* |
| 621 | ** 'strtof' and 'opf' variants for math functions are not valid in | |
| 622 | ** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the | |
| 623 | ** availability of these variants. ('math.h' is already included in | |
| 624 | ** all files that use these macros.) | |
| 476 | ** The next definitions activate some tricks to speed up the | |
| 477 | ** conversion from doubles to integer types, mainly to LUA_UNSIGNED. | |
| 478 | ** | |
| 479 | @@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a | |
| 480 | ** DirectX idiosyncrasy. | |
| 481 | ** | |
| 482 | @@ LUA_IEEE754TRICK uses a trick that should work on any machine | |
| 483 | ** using IEEE754 with a 32-bit integer type. | |
| 484 | ** | |
| 485 | @@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be | |
| 486 | ** defined when LUA_INTEGER is a 32-bit integer. | |
| 487 | ** | |
| 488 | @@ LUA_IEEEENDIAN is the endianness of doubles in your machine | |
| 489 | ** (0 for little endian, 1 for big endian); if not defined, Lua will | |
| 490 | ** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK). | |
| 491 | ** | |
| 492 | @@ LUA_NANTRICK controls the use of a trick to pack all types into | |
| 493 | ** a single double value, using NaN values to represent non-number | |
| 494 | ** values. The trick only works on 32-bit machines (ints and pointers | |
| 495 | ** are 32-bit values) with numbers represented as IEEE 754-2008 doubles | |
| 496 | ** with conventional endianess (12345678 or 87654321), in CPUs that do | |
| 497 | ** not produce signaling NaN values (all NaNs are quiet). | |
| 625 | 498 | */ |
| 626 | #if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF)) | |
| 627 | #undef l_mathop /* variants not available */ | |
| 628 | #undef lua_str2number | |
| 629 | #define l_mathop(op) (lua_Number)op /* no variant */ | |
| 630 | #define lua_str2number(s,p) ((lua_Number)strtod((s), (p))) | |
| 631 | #endif | |
| 632 | 499 | |
| 500 | /* Microsoft compiler on a Pentium (32 bit) ? */ | |
| 501 | #if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ | |
| 633 | 502 | |
| 634 | /* | |
| 635 | @@ LUA_KCONTEXT is the type of the context ('ctx') for continuation | |
| 636 | ** functions. It must be a numerical type; Lua will use 'intptr_t' if | |
| 637 | ** available, otherwise it will use 'ptrdiff_t' (the nearest thing to | |
| 638 | ** 'intptr_t' in C89) | |
| 639 | */ | |
| 640 | #define LUA_KCONTEXT ptrdiff_t | |
| 503 | #define LUA_MSASMTRICK | |
| 504 | #define LUA_IEEEENDIAN 0 | |
| 505 | #define LUA_NANTRICK | |
| 641 | 506 | |
| 642 | #if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ | |
| 643 | __STDC_VERSION__ >= 199901L | |
| 644 | #include <stdint.h> | |
| 645 | #if defined (INTPTR_MAX) /* even in C99 this type is optional */ | |
| 646 | #undef LUA_KCONTEXT | |
| 647 | #define LUA_KCONTEXT intptr_t | |
| 648 | #endif | |
| 649 | #endif | |
| 650 | 507 | |
| 651 | /* }================================================================== */ | |
| 508 | /* pentium 32 bits? */ | |
| 509 | #elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */ | |
| 652 | 510 | |
| 511 | #define LUA_IEEE754TRICK | |
| 512 | #define LUA_IEEELL | |
| 513 | #define LUA_IEEEENDIAN 0 | |
| 514 | #define LUA_NANTRICK | |
| 653 | 515 | |
| 654 | /* | |
| 655 | ** {================================================================== | |
| 656 | ** Macros that affect the API and must be stable (that is, must be the | |
| 657 | ** same when you compile Lua and when you compile code that links to | |
| 658 | ** Lua). You probably do not want/need to change them. | |
| 659 | ** ===================================================================== | |
| 660 | */ | |
| 516 | /* pentium 64 bits? */ | |
| 517 | #elif defined(__x86_64) /* }{ */ | |
| 661 | 518 | |
| 662 | /* | |
| 663 | @@ LUAI_MAXSTACK limits the size of the Lua stack. | |
| 664 | ** CHANGE it if you need a different limit. This limit is arbitrary; | |
| 665 | ** its only purpose is to stop Lua from consuming unlimited stack | |
| 666 | ** space (and to reserve some numbers for pseudo-indices). | |
| 667 | */ | |
| 668 | #if LUAI_BITSINT >= 32 | |
| 669 | #define LUAI_MAXSTACK 1000000 | |
| 670 | #else | |
| 671 | #define LUAI_MAXSTACK 15000 | |
| 672 | #endif | |
| 519 | #define LUA_IEEE754TRICK | |
| 520 | #define LUA_IEEEENDIAN 0 | |
| 673 | 521 | |
| 674 | /* reserve some space for error handling */ | |
| 675 | #define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) | |
| 522 | #elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ | |
| 676 | 523 | |
| 524 | #define LUA_IEEE754TRICK | |
| 525 | #define LUA_IEEEENDIAN 1 | |
| 677 | 526 | |
| 678 | /* | |
| 679 | @@ LUA_EXTRASPACE defines the size of a raw memory area associated with | |
| 680 | ** a Lua state with very fast access. | |
| 681 | ** CHANGE it if you need a different size. | |
| 682 | */ | |
| 683 | #define LUA_EXTRASPACE (sizeof(void *)) | |
| 527 | #else /* }{ */ | |
| 684 | 528 | |
| 529 | /* assume IEEE754 and a 32-bit integer type */ | |
| 530 | #define LUA_IEEE754TRICK | |
| 685 | 531 | |
| 686 | /* | |
| 687 | @@ LUA_IDSIZE gives the maximum size for the description of the source | |
| 688 | @@ of a function in debug information. | |
| 689 | ** CHANGE it if you want a different size. | |
| 690 | */ | |
| 691 | #define LUA_IDSIZE 60 | |
| 532 | #endif /* } */ | |
| 692 | 533 | |
| 534 | #endif /* } */ | |
| 693 | 535 | |
| 694 | /* | |
| 695 | @@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is, | |
| 696 | ** strings that are internalized. (Cannot be smaller than reserved words | |
| 697 | ** or tags for metamethods, as these strings must be internalized; | |
| 698 | ** #("function") = 8, #("__newindex") = 10.) | |
| 699 | */ | |
| 700 | #define LUAI_MAXSHORTLEN 40 | |
| 701 | ||
| 702 | ||
| 703 | /* | |
| 704 | @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. | |
| 705 | ** CHANGE it if it uses too much C-stack space. | |
| 706 | */ | |
| 707 | #define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer))) | |
| 708 | ||
| 709 | 536 | /* }================================================================== */ |
| 710 | 537 | |
| 711 | 538 | |
| 712 | /* | |
| 713 | @@ LUA_QL describes how error messages quote program elements. | |
| 714 | ** Lua does not use these macros anymore; they are here for | |
| 715 | ** compatibility only. | |
| 716 | */ | |
| 717 | #define LUA_QL(x) "'" x "'" | |
| 718 | #define LUA_QS LUA_QL("%s") | |
| 719 | 539 | |
| 720 | 540 | |
| 721 | ||
| 722 | ||
| 723 | 541 | /* =================================================================== */ |
| 724 | 542 | |
| 725 | 543 | /* |
| r242899 | r242900 | |
| 729 | 547 | |
| 730 | 548 | |
| 731 | 549 | |
| 732 | ||
| 733 | ||
| 734 | 550 | #endif |
| 735 | 551 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lualib.h,v 1.4 | |
| 2 | ** $Id: lualib.h,v 1.43.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lua standard libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 29 | 29 | #define LUA_STRLIBNAME "string" |
| 30 | 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 | ||
| 35 | 32 | #define LUA_BITLIBNAME "bit32" |
| 36 | 33 | LUAMOD_API int (luaopen_bit32) (lua_State *L); |
| 37 | 34 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lundump.c,v 2. | |
| 2 | ** $Id: lundump.c,v 2.22.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** load precompiled Lua chunks |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #include <string.h> | |
| 8 | ||
| 7 | 9 | #define lundump_c |
| 8 | 10 | #define LUA_CORE |
| 9 | 11 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <string.h> | |
| 14 | ||
| 15 | 12 | #include "lua.h" |
| 16 | 13 | |
| 17 | 14 | #include "ldebug.h" |
| r242899 | r242900 | |
| 23 | 20 | #include "lundump.h" |
| 24 | 21 | #include "lzio.h" |
| 25 | 22 | |
| 26 | ||
| 27 | #if !defined(luai_verifycode) | |
| 28 | #define luai_verifycode(L,b,f) /* empty */ | |
| 29 | #endif | |
| 30 | ||
| 31 | ||
| 32 | 23 | typedef struct { |
| 33 | lua_State *L; | |
| 34 | ZIO *Z; | |
| 35 | Mbuffer *b; | |
| 36 | const char *name; | |
| 24 | lua_State* L; | |
| 25 | ZIO* Z; | |
| 26 | Mbuffer* b; | |
| 27 | const char* name; | |
| 37 | 28 | } LoadState; |
| 38 | 29 | |
| 39 | ||
| 40 | static l_noret error(LoadState *S, const char *why) { | |
| 41 | luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); | |
| 42 | luaD_throw(S->L, LUA_ERRSYNTAX); | |
| 30 | static l_noret error(LoadState* S, const char* why) | |
| 31 | { | |
| 32 | luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); | |
| 33 | luaD_throw(S->L,LUA_ERRSYNTAX); | |
| 43 | 34 | } |
| 44 | 35 | |
| 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) | |
| 45 | 40 | |
| 46 | /* | |
| 47 | ** All high-level loads go through LoadVector; you can change it to | |
| 48 | ** adapt to the endianness of the input | |
| 49 | */ | |
| 50 | #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0])) | |
| 41 | #if !defined(luai_verifycode) | |
| 42 | #define luai_verifycode(L,b,f) /* empty */ | |
| 43 | #endif | |
| 51 | 44 | |
| 52 | static void LoadBlock (LoadState *S, void *b, size_t size) { | |
| 53 | if (luaZ_read(S->Z, b, size) != 0) | |
| 54 | error(S, "truncated"); | |
| 45 | static void LoadBlock(LoadState* S, void* b, size_t size) | |
| 46 | { | |
| 47 | if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); | |
| 55 | 48 | } |
| 56 | 49 | |
| 57 | ||
| 58 | #define LoadVar(S,x) LoadVector(S,&x,1) | |
| 59 | ||
| 60 | ||
| 61 | static lu_byte LoadByte (LoadState *S) { | |
| 62 | lu_byte x; | |
| 63 | LoadVar(S, x); | |
| 64 | return x; | |
| 50 | static int LoadChar(LoadState* S) | |
| 51 | { | |
| 52 | char x; | |
| 53 | LoadVar(S,x); | |
| 54 | return x; | |
| 65 | 55 | } |
| 66 | 56 | |
| 67 | ||
| 68 | static int LoadInt (LoadState *S) { | |
| 69 | int x; | |
| 70 | LoadVar(S, x); | |
| 71 | return x; | |
| 57 | static int LoadInt(LoadState* S) | |
| 58 | { | |
| 59 | int x; | |
| 60 | LoadVar(S,x); | |
| 61 | if (x<0) error(S,"corrupted"); | |
| 62 | return x; | |
| 72 | 63 | } |
| 73 | 64 | |
| 74 | ||
| 75 | static lua_Number LoadNumber (LoadState *S) { | |
| 76 | lua_Number x; | |
| 77 | LoadVar(S, x); | |
| 78 | return x; | |
| 65 | static lua_Number LoadNumber(LoadState* S) | |
| 66 | { | |
| 67 | lua_Number x; | |
| 68 | LoadVar(S,x); | |
| 69 | return x; | |
| 79 | 70 | } |
| 80 | 71 | |
| 81 | ||
| 82 | static lua_Integer LoadInteger (LoadState *S) { | |
| 83 | lua_Integer x; | |
| 84 | LoadVar(S, x); | |
| 85 | return x; | |
| 72 | static TString* LoadString(LoadState* S) | |
| 73 | { | |
| 74 | size_t size; | |
| 75 | LoadVar(S,size); | |
| 76 | if (size==0) | |
| 77 | return NULL; | |
| 78 | else | |
| 79 | { | |
| 80 | char* s=luaZ_openspace(S->L,S->b,size); | |
| 81 | LoadBlock(S,s,size*sizeof(char)); | |
| 82 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ | |
| 83 | } | |
| 86 | 84 | } |
| 87 | 85 | |
| 88 | ||
| 89 | static TString *LoadString (LoadState *S) { | |
| 90 | size_t size = LoadByte(S); | |
| 91 | if (size == 0xFF) | |
| 92 | LoadVar(S, size); | |
| 93 | if (size == 0) | |
| 94 | return NULL; | |
| 95 | else { | |
| 96 | char *s = luaZ_openspace(S->L, S->b, --size); | |
| 97 | LoadVector(S, s, size); | |
| 98 | return luaS_newlstr(S->L, s, size); | |
| 99 | } | |
| 86 | static void LoadCode(LoadState* S, Proto* f) | |
| 87 | { | |
| 88 | int n=LoadInt(S); | |
| 89 | f->code=luaM_newvector(S->L,n,Instruction); | |
| 90 | f->sizecode=n; | |
| 91 | LoadVector(S,f->code,n,sizeof(Instruction)); | |
| 100 | 92 | } |
| 101 | 93 | |
| 94 | static void LoadFunction(LoadState* S, Proto* f); | |
| 102 | 95 | |
| 103 | static void LoadCode (LoadState *S, Proto *f) { | |
| 104 | int n = LoadInt(S); | |
| 105 | f->code = luaM_newvector(S->L, n, Instruction); | |
| 106 | f->sizecode = n; | |
| 107 | LoadVector(S, f->code, n); | |
| 108 | } | |
| 109 | ||
| 110 | ||
| 111 | static void LoadFunction(LoadState *S, Proto *f, TString *psource); | |
| 112 | ||
| 113 | ||
| 114 | static void LoadConstants (LoadState *S, Proto *f) { | |
| 115 | int i; | |
| 116 | int n = LoadInt(S); | |
| 117 | f->k = luaM_newvector(S->L, n, TValue); | |
| 118 | f->sizek = n; | |
| 119 | for (i = 0; i < n; i++) | |
| 120 | setnilvalue(&f->k[i]); | |
| 121 | for (i = 0; i < n; i++) { | |
| 122 | TValue *o = &f->k[i]; | |
| 123 | int t = LoadByte(S); | |
| 124 | switch (t) { | |
| 125 | case LUA_TNIL: | |
| 126 | setnilvalue(o); | |
| 127 | break; | |
| 128 | case LUA_TBOOLEAN: | |
| 129 | setbvalue(o, LoadByte(S)); | |
| 130 | break; | |
| 131 | case LUA_TNUMFLT: | |
| 132 | setfltvalue(o, LoadNumber(S)); | |
| 133 | break; | |
| 134 | case LUA_TNUMINT: | |
| 135 | setivalue(o, LoadInteger(S)); | |
| 136 | break; | |
| 137 | case LUA_TSHRSTR: | |
| 138 | case LUA_TLNGSTR: | |
| 139 | setsvalue2n(S->L, o, LoadString(S)); | |
| 140 | break; | |
| 141 | default: | |
| 142 | lua_assert(0); | |
| 143 | } | |
| 96 | static void LoadConstants(LoadState* S, Proto* f) | |
| 97 | { | |
| 98 | int i,n; | |
| 99 | n=LoadInt(S); | |
| 100 | f->k=luaM_newvector(S->L,n,TValue); | |
| 101 | f->sizek=n; | |
| 102 | for (i=0; i<n; i++) setnilvalue(&f->k[i]); | |
| 103 | for (i=0; i<n; i++) | |
| 104 | { | |
| 105 | TValue* o=&f->k[i]; | |
| 106 | int t=LoadChar(S); | |
| 107 | switch (t) | |
| 108 | { | |
| 109 | case LUA_TNIL: | |
| 110 | setnilvalue(o); | |
| 111 | break; | |
| 112 | case LUA_TBOOLEAN: | |
| 113 | setbvalue(o,LoadChar(S)); | |
| 114 | break; | |
| 115 | case LUA_TNUMBER: | |
| 116 | setnvalue(o,LoadNumber(S)); | |
| 117 | break; | |
| 118 | case LUA_TSTRING: | |
| 119 | setsvalue2n(S->L,o,LoadString(S)); | |
| 120 | break; | |
| 121 | default: lua_assert(0); | |
| 144 | 122 | } |
| 123 | } | |
| 124 | n=LoadInt(S); | |
| 125 | f->p=luaM_newvector(S->L,n,Proto*); | |
| 126 | f->sizep=n; | |
| 127 | for (i=0; i<n; i++) f->p[i]=NULL; | |
| 128 | for (i=0; i<n; i++) | |
| 129 | { | |
| 130 | f->p[i]=luaF_newproto(S->L); | |
| 131 | LoadFunction(S,f->p[i]); | |
| 132 | } | |
| 145 | 133 | } |
| 146 | 134 | |
| 147 | ||
| 148 | static void LoadProtos (LoadState *S, Proto *f) { | |
| 149 | int i; | |
| 150 | int n = LoadInt(S); | |
| 151 | f->p = luaM_newvector(S->L, n, Proto *); | |
| 152 | f->sizep = n; | |
| 153 | for (i = 0; i < n; i++) | |
| 154 | f->p[i] = NULL; | |
| 155 | for (i = 0; i < n; i++) { | |
| 156 | f->p[i] = luaF_newproto(S->L); | |
| 157 | LoadFunction(S, f->p[i], f->source); | |
| 158 | } | |
| 135 | static void LoadUpvalues(LoadState* S, Proto* f) | |
| 136 | { | |
| 137 | int i,n; | |
| 138 | n=LoadInt(S); | |
| 139 | f->upvalues=luaM_newvector(S->L,n,Upvaldesc); | |
| 140 | f->sizeupvalues=n; | |
| 141 | for (i=0; i<n; i++) f->upvalues[i].name=NULL; | |
| 142 | for (i=0; i<n; i++) | |
| 143 | { | |
| 144 | f->upvalues[i].instack=LoadByte(S); | |
| 145 | f->upvalues[i].idx=LoadByte(S); | |
| 146 | } | |
| 159 | 147 | } |
| 160 | 148 | |
| 161 | ||
| 162 | static void LoadUpvalues (LoadState *S, Proto *f) { | |
| 163 | int i, n; | |
| 164 | n = LoadInt(S); | |
| 165 | f->upvalues = luaM_newvector(S->L, n, Upvaldesc); | |
| 166 | f->sizeupvalues = n; | |
| 167 | for (i = 0; i < n; i++) | |
| 168 | f->upvalues[i].name = NULL; | |
| 169 | for (i = 0; i < n; i++) { | |
| 170 | f->upvalues[i].instack = LoadByte(S); | |
| 171 | f->upvalues[i].idx = LoadByte(S); | |
| 172 | } | |
| 149 | static void LoadDebug(LoadState* S, Proto* f) | |
| 150 | { | |
| 151 | int i,n; | |
| 152 | f->source=LoadString(S); | |
| 153 | n=LoadInt(S); | |
| 154 | f->lineinfo=luaM_newvector(S->L,n,int); | |
| 155 | f->sizelineinfo=n; | |
| 156 | LoadVector(S,f->lineinfo,n,sizeof(int)); | |
| 157 | n=LoadInt(S); | |
| 158 | f->locvars=luaM_newvector(S->L,n,LocVar); | |
| 159 | f->sizelocvars=n; | |
| 160 | for (i=0; i<n; i++) f->locvars[i].varname=NULL; | |
| 161 | for (i=0; i<n; i++) | |
| 162 | { | |
| 163 | f->locvars[i].varname=LoadString(S); | |
| 164 | f->locvars[i].startpc=LoadInt(S); | |
| 165 | f->locvars[i].endpc=LoadInt(S); | |
| 166 | } | |
| 167 | n=LoadInt(S); | |
| 168 | for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S); | |
| 173 | 169 | } |
| 174 | 170 | |
| 175 | ||
| 176 | static void LoadDebug (LoadState *S, Proto *f) { | |
| 177 | int i, n; | |
| 178 | n = LoadInt(S); | |
| 179 | f->lineinfo = luaM_newvector(S->L, n, int); | |
| 180 | f->sizelineinfo = n; | |
| 181 | LoadVector(S, f->lineinfo, n); | |
| 182 | n = LoadInt(S); | |
| 183 | f->locvars = luaM_newvector(S->L, n, LocVar); | |
| 184 | f->sizelocvars = n; | |
| 185 | for (i = 0; i < n; i++) | |
| 186 | f->locvars[i].varname = NULL; | |
| 187 | for (i = 0; i < n; i++) { | |
| 188 | f->locvars[i].varname = LoadString(S); | |
| 189 | f->locvars[i].startpc = LoadInt(S); | |
| 190 | f->locvars[i].endpc = LoadInt(S); | |
| 191 | } | |
| 192 | n = LoadInt(S); | |
| 193 | for (i = 0; i < n; i++) | |
| 194 | f->upvalues[i].name = LoadString(S); | |
| 171 | static void LoadFunction(LoadState* S, Proto* f) | |
| 172 | { | |
| 173 | f->linedefined=LoadInt(S); | |
| 174 | f->lastlinedefined=LoadInt(S); | |
| 175 | f->numparams=LoadByte(S); | |
| 176 | f->is_vararg=LoadByte(S); | |
| 177 | f->maxstacksize=LoadByte(S); | |
| 178 | LoadCode(S,f); | |
| 179 | LoadConstants(S,f); | |
| 180 | LoadUpvalues(S,f); | |
| 181 | LoadDebug(S,f); | |
| 195 | 182 | } |
| 196 | 183 | |
| 184 | /* the code below must be consistent with the code in luaU_header */ | |
| 185 | #define N0 LUAC_HEADERSIZE | |
| 186 | #define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) | |
| 187 | #define N2 N1+2 | |
| 188 | #define N3 N2+6 | |
| 197 | 189 | |
| 198 | static void LoadFunction (LoadState *S, Proto *f, TString *psource) { | |
| 199 | f->source = LoadString(S); | |
| 200 | if (f->source == NULL) /* no source in dump? */ | |
| 201 | f->source = psource; /* reuse parent's source */ | |
| 202 | f->linedefined = LoadInt(S); | |
| 203 | f->lastlinedefined = LoadInt(S); | |
| 204 | f->numparams = LoadByte(S); | |
| 205 | f->is_vararg = LoadByte(S); | |
| 206 | f->maxstacksize = LoadByte(S); | |
| 207 | LoadCode(S, f); | |
| 208 | LoadConstants(S, f); | |
| 209 | LoadUpvalues(S, f); | |
| 210 | LoadProtos(S, f); | |
| 211 | LoadDebug(S, f); | |
| 190 | static void LoadHeader(LoadState* S) | |
| 191 | { | |
| 192 | lu_byte h[LUAC_HEADERSIZE]; | |
| 193 | lu_byte s[LUAC_HEADERSIZE]; | |
| 194 | luaU_header(h); | |
| 195 | memcpy(s,h,sizeof(char)); /* first char already read */ | |
| 196 | LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); | |
| 197 | if (memcmp(h,s,N0)==0) return; | |
| 198 | if (memcmp(h,s,N1)!=0) error(S,"not a"); | |
| 199 | if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); | |
| 200 | if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); | |
| 212 | 201 | } |
| 213 | 202 | |
| 214 | ||
| 215 | static void checkliteral (LoadState *S, const char *s, const char *msg) { | |
| 216 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ | |
| 217 | size_t len = strlen(s); | |
| 218 | LoadVector(S, buff, len); | |
| 219 | if (memcmp(s, buff, len) != 0) | |
| 220 | error(S, msg); | |
| 203 | /* | |
| 204 | ** load precompiled chunk | |
| 205 | */ | |
| 206 | Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) | |
| 207 | { | |
| 208 | LoadState S; | |
| 209 | Closure* cl; | |
| 210 | if (*name=='@' || *name=='=') | |
| 211 | S.name=name+1; | |
| 212 | else if (*name==LUA_SIGNATURE[0]) | |
| 213 | S.name="binary string"; | |
| 214 | else | |
| 215 | S.name=name; | |
| 216 | S.L=L; | |
| 217 | S.Z=Z; | |
| 218 | S.b=buff; | |
| 219 | LoadHeader(&S); | |
| 220 | cl=luaF_newLclosure(L,1); | |
| 221 | setclLvalue(L,L->top,cl); incr_top(L); | |
| 222 | cl->l.p=luaF_newproto(L); | |
| 223 | LoadFunction(&S,cl->l.p); | |
| 224 | if (cl->l.p->sizeupvalues != 1) | |
| 225 | { | |
| 226 | Proto* p=cl->l.p; | |
| 227 | cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); | |
| 228 | cl->l.p=p; | |
| 229 | setclLvalue(L,L->top-1,cl); | |
| 230 | } | |
| 231 | luai_verifycode(L,buff,cl->l.p); | |
| 232 | return cl; | |
| 221 | 233 | } |
| 222 | 234 | |
| 235 | #define MYINT(s) (s[0]-'0') | |
| 236 | #define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) | |
| 237 | #define FORMAT 0 /* this is the official format */ | |
| 223 | 238 | |
| 224 | static void fchecksize (LoadState *S, size_t size, const char *tname) { | |
| 225 | if (LoadByte(S) != size) | |
| 226 | error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); | |
| 227 | } | |
| 228 | ||
| 229 | ||
| 230 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) | |
| 231 | ||
| 232 | static void checkHeader (LoadState *S) { | |
| 233 | checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */ | |
| 234 | if (LoadByte(S) != LUAC_VERSION) | |
| 235 | error(S, "version mismatch in"); | |
| 236 | if (LoadByte(S) != LUAC_FORMAT) | |
| 237 | error(S, "format mismatch in"); | |
| 238 | checkliteral(S, LUAC_DATA, "corrupted"); | |
| 239 | checksize(S, int); | |
| 240 | checksize(S, size_t); | |
| 241 | checksize(S, Instruction); | |
| 242 | checksize(S, lua_Integer); | |
| 243 | checksize(S, lua_Number); | |
| 244 | if (LoadInteger(S) != LUAC_INT) | |
| 245 | error(S, "endianness mismatch in"); | |
| 246 | if (LoadNumber(S) != LUAC_NUM) | |
| 247 | error(S, "float format mismatch in"); | |
| 248 | } | |
| 249 | ||
| 250 | ||
| 251 | 239 | /* |
| 252 | ** load precompiled chunk | |
| 240 | * make header for precompiled chunks | |
| 241 | * if you change the code below be sure to update LoadHeader and FORMAT above | |
| 242 | * and LUAC_HEADERSIZE in lundump.h | |
| 253 | 243 | */ |
| 254 | LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff, | |
| 255 | const char *name) { | |
| 256 | LoadState S; | |
| 257 | LClosure *cl; | |
| 258 | if (*name == '@' || *name == '=') | |
| 259 | S.name = name + 1; | |
| 260 | else if (*name == LUA_SIGNATURE[0]) | |
| 261 | S.name = "binary string"; | |
| 262 | else | |
| 263 | S.name = name; | |
| 264 | S.L = L; | |
| 265 | S.Z = Z; | |
| 266 | S.b = buff; | |
| 267 | checkHeader(&S); | |
| 268 | cl = luaF_newLclosure(L, LoadByte(&S)); | |
| 269 | setclLvalue(L, L->top, cl); | |
| 270 | incr_top(L); | |
| 271 | cl->p = luaF_newproto(L); | |
| 272 | LoadFunction(&S, cl->p, NULL); | |
| 273 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); | |
| 274 | luai_verifycode(L, buff, cl->p); | |
| 275 | return cl; | |
| 244 | void luaU_header (lu_byte* h) | |
| 245 | { | |
| 246 | int x=1; | |
| 247 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); | |
| 248 | h+=sizeof(LUA_SIGNATURE)-sizeof(char); | |
| 249 | *h++=cast_byte(VERSION); | |
| 250 | *h++=cast_byte(FORMAT); | |
| 251 | *h++=cast_byte(*(char*)&x); /* endianness */ | |
| 252 | *h++=cast_byte(sizeof(int)); | |
| 253 | *h++=cast_byte(sizeof(size_t)); | |
| 254 | *h++=cast_byte(sizeof(Instruction)); | |
| 255 | *h++=cast_byte(sizeof(lua_Number)); | |
| 256 | *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ | |
| 257 | memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); | |
| 276 | 258 | } |
| 277 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lundump.h,v 1. | |
| 2 | ** $Id: lundump.h,v 1.39.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** load precompiled Lua chunks |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 7 | 7 | #ifndef lundump_h |
| 8 | 8 | #define lundump_h |
| 9 | 9 | |
| 10 | #include "llimits.h" | |
| 11 | 10 | #include "lobject.h" |
| 12 | 11 | #include "lzio.h" |
| 13 | 12 | |
| 13 | /* load one chunk; from lundump.c */ | |
| 14 | LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); | |
| 14 | 15 | |
| 15 | /* data to catch conversion errors */ | |
| 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" | |
| 16 | /* make header; from lundump.c */ | |
| 17 | LUAI_FUNC void luaU_header (lu_byte* h); | |
| 17 | 18 | |
| 18 | #define LUAC_INT 0x5678 | |
| 19 | #define LUAC_NUM cast_num(370.5) | |
| 19 | /* dump one chunk; from ldump.c */ | |
| 20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); | |
| 20 | 21 | |
| 21 | #define MYINT(s) (s[0]-'0') | |
| 22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) | |
| 23 | #define LUAC_FORMAT 0 /* this is the official format */ | |
| 22 | /* data to catch conversion errors */ | |
| 23 | #define LUAC_TAIL "\x19\x93\r\n\x1a\n" | |
| 24 | 24 | |
| 25 | /* load one chunk; from lundump.c */ | |
| 26 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, | |
| 27 | const char* name); | |
| 25 | /* size in bytes of header of binary files */ | |
| 26 | #define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) | |
| 28 | 27 | |
| 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); | |
| 32 | ||
| 33 | 28 | #endif |
| r242899 | r242900 | |
|---|---|---|
| 1 | /* | |
| 2 | ** $Id: lutf8lib.c,v 1.13 2014/11/02 19:19:04 roberto Exp $ | |
| 3 | ** Standard library for UTF-8 manipulation | |
| 4 | ** See Copyright Notice in lua.h | |
| 5 | */ | |
| 6 | ||
| 7 | #define lutf8lib_c | |
| 8 | #define LUA_LIB | |
| 9 | ||
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <assert.h> | |
| 14 | #include <stdlib.h> | |
| 15 | #include <string.h> | |
| 16 | ||
| 17 | #include "lua.h" | |
| 18 | ||
| 19 | #include "lauxlib.h" | |
| 20 | #include "lualib.h" | |
| 21 | ||
| 22 | #define MAXUNICODE 0x10FFFF | |
| 23 | ||
| 24 | #define iscont(p) ((*(p) & 0xC0) == 0x80) | |
| 25 | ||
| 26 | ||
| 27 | /* from strlib */ | |
| 28 | /* translate a relative string position: negative means back from end */ | |
| 29 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { | |
| 30 | if (pos >= 0) return pos; | |
| 31 | else if (0u - (size_t)pos > len) return 0; | |
| 32 | else return (lua_Integer)len + pos + 1; | |
| 33 | } | |
| 34 | ||
| 35 | ||
| 36 | /* | |
| 37 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. | |
| 38 | */ | |
| 39 | static const char *utf8_decode (const char *o, int *val) { | |
| 40 | static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; | |
| 41 | const unsigned char *s = (const unsigned char *)o; | |
| 42 | unsigned int c = s[0]; | |
| 43 | unsigned int res = 0; /* final result */ | |
| 44 | if (c < 0x80) /* ascii? */ | |
| 45 | res = c; | |
| 46 | else { | |
| 47 | int count = 0; /* to count number of continuation bytes */ | |
| 48 | while (c & 0x40) { /* still have continuation bytes? */ | |
| 49 | int cc = s[++count]; /* read next byte */ | |
| 50 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ | |
| 51 | return NULL; /* invalid byte sequence */ | |
| 52 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ | |
| 53 | c <<= 1; /* to test next bit */ | |
| 54 | } | |
| 55 | res |= ((c & 0x7F) << (count * 5)); /* add first byte */ | |
| 56 | if (count > 3 || res > MAXUNICODE || res <= limits[count]) | |
| 57 | return NULL; /* invalid byte sequence */ | |
| 58 | s += count; /* skip continuation bytes read */ | |
| 59 | } | |
| 60 | if (val) *val = res; | |
| 61 | return (const char *)s + 1; /* +1 to include first byte */ | |
| 62 | } | |
| 63 | ||
| 64 | ||
| 65 | /* | |
| 66 | ** utf8len(s [, i [, j]]) --> number of characters that start in the | |
| 67 | ** range [i,j], or nil + current position if 's' is not well formed in | |
| 68 | ** that interval | |
| 69 | */ | |
| 70 | static int utflen (lua_State *L) { | |
| 71 | int n = 0; | |
| 72 | size_t len; | |
| 73 | const char *s = luaL_checklstring(L, 1, &len); | |
| 74 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); | |
| 75 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); | |
| 76 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, | |
| 77 | "initial position out of string"); | |
| 78 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, | |
| 79 | "final position out of string"); | |
| 80 | while (posi <= posj) { | |
| 81 | const char *s1 = utf8_decode(s + posi, NULL); | |
| 82 | if (s1 == NULL) { /* conversion error? */ | |
| 83 | lua_pushnil(L); /* return nil ... */ | |
| 84 | lua_pushinteger(L, posi + 1); /* ... and current position */ | |
| 85 | return 2; | |
| 86 | } | |
| 87 | posi = s1 - s; | |
| 88 | n++; | |
| 89 | } | |
| 90 | lua_pushinteger(L, n); | |
| 91 | return 1; | |
| 92 | } | |
| 93 | ||
| 94 | ||
| 95 | /* | |
| 96 | ** codepoint(s, [i, [j]]) -> returns codepoints for all characters | |
| 97 | ** that start in the range [i,j] | |
| 98 | */ | |
| 99 | static int codepoint (lua_State *L) { | |
| 100 | size_t len; | |
| 101 | const char *s = luaL_checklstring(L, 1, &len); | |
| 102 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); | |
| 103 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); | |
| 104 | int n; | |
| 105 | const char *se; | |
| 106 | luaL_argcheck(L, posi >= 1, 2, "out of range"); | |
| 107 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); | |
| 108 | if (posi > pose) return 0; /* empty interval; return no values */ | |
| 109 | n = (int)(pose - posi + 1); | |
| 110 | if (posi + n <= pose) /* (lua_Integer -> int) overflow? */ | |
| 111 | return luaL_error(L, "string slice too long"); | |
| 112 | luaL_checkstack(L, n, "string slice too long"); | |
| 113 | n = 0; | |
| 114 | se = s + pose; | |
| 115 | for (s += posi - 1; s < se;) { | |
| 116 | int code; | |
| 117 | s = utf8_decode(s, &code); | |
| 118 | if (s == NULL) | |
| 119 | return luaL_error(L, "invalid UTF-8 code"); | |
| 120 | lua_pushinteger(L, code); | |
| 121 | n++; | |
| 122 | } | |
| 123 | return n; | |
| 124 | } | |
| 125 | ||
| 126 | ||
| 127 | static void pushutfchar (lua_State *L, int arg) { | |
| 128 | lua_Integer code = luaL_checkinteger(L, arg); | |
| 129 | luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); | |
| 130 | lua_pushfstring(L, "%U", (long)code); | |
| 131 | } | |
| 132 | ||
| 133 | ||
| 134 | /* | |
| 135 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... | |
| 136 | */ | |
| 137 | static int utfchar (lua_State *L) { | |
| 138 | int n = lua_gettop(L); /* number of arguments */ | |
| 139 | if (n == 1) /* optimize common case of single char */ | |
| 140 | pushutfchar(L, 1); | |
| 141 | else { | |
| 142 | int i; | |
| 143 | luaL_Buffer b; | |
| 144 | luaL_buffinit(L, &b); | |
| 145 | for (i = 1; i <= n; i++) { | |
| 146 | pushutfchar(L, i); | |
| 147 | luaL_addvalue(&b); | |
| 148 | } | |
| 149 | luaL_pushresult(&b); | |
| 150 | } | |
| 151 | return 1; | |
| 152 | } | |
| 153 | ||
| 154 | ||
| 155 | /* | |
| 156 | ** offset(s, n, [i]) -> index where n-th character counting from | |
| 157 | ** position 'i' starts; 0 means character at 'i'. | |
| 158 | */ | |
| 159 | static int byteoffset (lua_State *L) { | |
| 160 | size_t len; | |
| 161 | const char *s = luaL_checklstring(L, 1, &len); | |
| 162 | lua_Integer n = luaL_checkinteger(L, 2); | |
| 163 | lua_Integer posi = (n >= 0) ? 1 : len + 1; | |
| 164 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); | |
| 165 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, | |
| 166 | "position out of range"); | |
| 167 | if (n == 0) { | |
| 168 | /* find beginning of current byte sequence */ | |
| 169 | while (posi > 0 && iscont(s + posi)) posi--; | |
| 170 | } | |
| 171 | else { | |
| 172 | if (iscont(s + posi)) | |
| 173 | luaL_error(L, "initial position is a continuation byte"); | |
| 174 | if (n < 0) { | |
| 175 | while (n < 0 && posi > 0) { /* move back */ | |
| 176 | do { /* find beginning of previous character */ | |
| 177 | posi--; | |
| 178 | } while (posi > 0 && iscont(s + posi)); | |
| 179 | n++; | |
| 180 | } | |
| 181 | } | |
| 182 | else { | |
| 183 | n--; /* do not move for 1st character */ | |
| 184 | while (n > 0 && posi < (lua_Integer)len) { | |
| 185 | do { /* find beginning of next character */ | |
| 186 | posi++; | |
| 187 | } while (iscont(s + posi)); /* (cannot pass final '\0') */ | |
| 188 | n--; | |
| 189 | } | |
| 190 | } | |
| 191 | } | |
| 192 | if (n == 0) /* did it find given character? */ | |
| 193 | lua_pushinteger(L, posi + 1); | |
| 194 | else /* no such character */ | |
| 195 | lua_pushnil(L); | |
| 196 | return 1; | |
| 197 | } | |
| 198 | ||
| 199 | ||
| 200 | static int iter_aux (lua_State *L) { | |
| 201 | size_t len; | |
| 202 | const char *s = luaL_checklstring(L, 1, &len); | |
| 203 | lua_Integer n = lua_tointeger(L, 2) - 1; | |
| 204 | if (n < 0) /* first iteration? */ | |
| 205 | n = 0; /* start from here */ | |
| 206 | else if (n < (lua_Integer)len) { | |
| 207 | n++; /* skip current byte */ | |
| 208 | while (iscont(s + n)) n++; /* and its continuations */ | |
| 209 | } | |
| 210 | if (n >= (lua_Integer)len) | |
| 211 | return 0; /* no more codepoints */ | |
| 212 | else { | |
| 213 | int code; | |
| 214 | const char *next = utf8_decode(s + n, &code); | |
| 215 | if (next == NULL || iscont(next)) | |
| 216 | return luaL_error(L, "invalid UTF-8 code"); | |
| 217 | lua_pushinteger(L, n + 1); | |
| 218 | lua_pushinteger(L, code); | |
| 219 | return 2; | |
| 220 | } | |
| 221 | } | |
| 222 | ||
| 223 | ||
| 224 | static int iter_codes (lua_State *L) { | |
| 225 | luaL_checkstring(L, 1); | |
| 226 | lua_pushcfunction(L, iter_aux); | |
| 227 | lua_pushvalue(L, 1); | |
| 228 | lua_pushinteger(L, 0); | |
| 229 | return 3; | |
| 230 | } | |
| 231 | ||
| 232 | ||
| 233 | /* pattern to match a single UTF-8 character */ | |
| 234 | #define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" | |
| 235 | ||
| 236 | ||
| 237 | static struct luaL_Reg funcs[] = { | |
| 238 | {"offset", byteoffset}, | |
| 239 | {"codepoint", codepoint}, | |
| 240 | {"char", utfchar}, | |
| 241 | {"len", utflen}, | |
| 242 | {"codes", iter_codes}, | |
| 243 | /* placeholders */ | |
| 244 | {"charpattern", NULL}, | |
| 245 | {NULL, NULL} | |
| 246 | }; | |
| 247 | ||
| 248 | ||
| 249 | LUAMOD_API int luaopen_utf8 (lua_State *L) { | |
| 250 | luaL_newlib(L, funcs); | |
| 251 | lua_pushliteral(L, UTF8PATT); | |
| 252 | lua_setfield(L, -2, "charpattern"); | |
| 253 | return 1; | |
| 254 | } | |
| 255 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lvm.c,v 2. | |
| 2 | ** $Id: lvm.c,v 2.155.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lvm_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | #include <limits.h> | |
| 14 | 8 | #include <stdio.h> |
| 15 | 9 | #include <stdlib.h> |
| 16 | 10 | #include <string.h> |
| 17 | 11 | |
| 12 | #define lvm_c | |
| 13 | #define LUA_CORE | |
| 14 | ||
| 18 | 15 | #include "lua.h" |
| 19 | 16 | |
| 20 | 17 | #include "ldebug.h" |
| r242899 | r242900 | |
| 30 | 27 | #include "lvm.h" |
| 31 | 28 | |
| 32 | 29 | |
| 33 | /* | |
| 34 | ** You can define LUA_FLOORN2I if you want to convert floats to integers | |
| 35 | ** by flooring them (instead of raising an error if they are not | |
| 36 | ** integral values) | |
| 37 | */ | |
| 38 | #if !defined(LUA_FLOORN2I) | |
| 39 | #define LUA_FLOORN2I 0 | |
| 40 | #endif | |
| 41 | 30 | |
| 42 | ||
| 43 | 31 | /* limit for table tag-method chains (to avoid loops) */ |
| 44 | #define MAXTAGLOOP | |
| 32 | #define MAXTAGLOOP 100 | |
| 45 | 33 | |
| 46 | 34 | |
| 47 | /* | |
| 48 | ** Similar to 'tonumber', but does not attempt to convert strings and | |
| 49 | ** ensure correct precision (no extra bits). Used in comparisons. | |
| 50 | */ | |
| 51 | static int tofloat (const TValue *obj, lua_Number *n) { | |
| 52 | if (ttisfloat(obj)) *n = fltvalue(obj); | |
| 53 | else if (ttisinteger(obj)) { | |
| 54 | volatile lua_Number x = cast_num(ivalue(obj)); /* avoid extra precision */ | |
| 55 | *n = x; | |
| 35 | const TValue *luaV_tonumber (const TValue *obj, TValue *n) { | |
| 36 | lua_Number num; | |
| 37 | if (ttisnumber(obj)) return obj; | |
| 38 | if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) { | |
| 39 | setnvalue(n, num); | |
| 40 | return n; | |
| 56 | 41 | } |
| 57 | else { | |
| 58 | *n = 0; /* to avoid warnings */ | |
| 59 | return 0; | |
| 60 | } | |
| 61 | return 1; | |
| 42 | else | |
| 43 | return NULL; | |
| 62 | 44 | } |
| 63 | 45 | |
| 64 | 46 | |
| 65 | /* | |
| 66 | ** Try to convert a value to a float. The float case is already handled | |
| 67 | ** by the macro 'tonumber'. | |
| 68 | */ | |
| 69 | int luaV_tonumber_ (const TValue *obj, lua_Number *n) { | |
| 70 | TValue v; | |
| 71 | if (ttisinteger(obj)) { | |
| 72 | *n = cast_num(ivalue(obj)); | |
| 47 | int luaV_tostring (lua_State *L, StkId obj) { | |
| 48 | if (!ttisnumber(obj)) | |
| 49 | return 0; | |
| 50 | else { | |
| 51 | char s[LUAI_MAXNUMBER2STR]; | |
| 52 | lua_Number n = nvalue(obj); | |
| 53 | int l = lua_number2str(s, n); | |
| 54 | setsvalue2s(L, obj, luaS_newlstr(L, s, l)); | |
| 73 | 55 | return 1; |
| 74 | 56 | } |
| 75 | else if (cvt2num(obj) && /* string convertible to number? */ | |
| 76 | luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) { | |
| 77 | *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ | |
| 78 | return 1; | |
| 79 | } | |
| 80 | else | |
| 81 | return 0; /* conversion failed */ | |
| 82 | 57 | } |
| 83 | 58 | |
| 84 | 59 | |
| 85 | /* | |
| 86 | ** try to convert a value to an integer, rounding according to 'mode': | |
| 87 | ** mode == 0: accepts only integral values | |
| 88 | ** mode == 1: takes the floor of the number | |
| 89 | ** mode == 2: takes the ceil of the number | |
| 90 | */ | |
| 91 | static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) { | |
| 92 | TValue v; | |
| 93 | again: | |
| 94 | if (ttisfloat(obj)) { | |
| 95 | lua_Number n = fltvalue(obj); | |
| 96 | lua_Number f = l_floor(n); | |
| 97 | if (n != f) { /* not an integral value? */ | |
| 98 | if (mode == 0) return 0; /* fails if mode demands integral value */ | |
| 99 | else if (mode > 1) /* needs ceil? */ | |
| 100 | f += 1; /* convert floor to ceil (remember: n != f) */ | |
| 101 | } | |
| 102 | return lua_numbertointeger(f, p); | |
| 60 | static void traceexec (lua_State *L) { | |
| 61 | CallInfo *ci = L->ci; | |
| 62 | lu_byte mask = L->hookmask; | |
| 63 | int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); | |
| 64 | if (counthook) | |
| 65 | resethookcount(L); /* reset count */ | |
| 66 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ | |
| 67 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ | |
| 68 | return; /* do not call hook again (VM yielded, so it did not move) */ | |
| 103 | 69 | } |
| 104 | else if (ttisinteger(obj)) { | |
| 105 | *p = ivalue(obj); | |
| 106 | return 1; | |
| 70 | if (counthook) | |
| 71 | luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ | |
| 72 | if (mask & LUA_MASKLINE) { | |
| 73 | Proto *p = ci_func(ci)->p; | |
| 74 | int npc = pcRel(ci->u.l.savedpc, p); | |
| 75 | int newline = getfuncline(p, npc); | |
| 76 | if (npc == 0 || /* call linehook when enter a new function, */ | |
| 77 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ | |
| 78 | newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ | |
| 79 | luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ | |
| 107 | 80 | } |
| 108 | else if (cvt2num(obj) && | |
| 109 | luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) { | |
| 110 | obj = &v; | |
| 111 | goto again; /* convert result from 'luaO_str2num' to an integer */ | |
| 81 | L->oldpc = ci->u.l.savedpc; | |
| 82 | if (L->status == LUA_YIELD) { /* did hook yield? */ | |
| 83 | if (counthook) | |
| 84 | L->hookcount = 1; /* undo decrement to zero */ | |
| 85 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ | |
| 86 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ | |
| 87 | ci->func = L->top - 1; /* protect stack below results */ | |
| 88 | luaD_throw(L, LUA_YIELD); | |
| 112 | 89 | } |
| 113 | return 0; /* conversion failed */ | |
| 114 | 90 | } |
| 115 | 91 | |
| 116 | 92 | |
| 117 | /* | |
| 118 | ** try to convert a value to an integer | |
| 119 | */ | |
| 120 | int luaV_tointeger_ (const TValue *obj, lua_Integer *p) { | |
| 121 | return tointeger_aux(obj, p, LUA_FLOORN2I); | |
| 122 | } | |
| 123 | ||
| 124 | ||
| 125 | /* | |
| 126 | ** Try to convert a 'for' limit to an integer, preserving the | |
| 127 | ** semantics of the loop. | |
| 128 | ** (The following explanation assumes a non-negative step; it is valid | |
| 129 | ** for negative steps mutatis mutandis.) | |
| 130 | ** If the limit can be converted to an integer, rounding down, that is | |
| 131 | ** it. | |
| 132 | ** Otherwise, check whether the limit can be converted to a number. If | |
| 133 | ** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, | |
| 134 | ** which means no limit. If the number is too negative, the loop | |
| 135 | ** should not run, because any initial integer value is larger than the | |
| 136 | ** limit. So, it sets the limit to LUA_MININTEGER. 'stopnow' corrects | |
| 137 | ** the extreme case when the initial value is LUA_MININTEGER, in which | |
| 138 | ** case the LUA_MININTEGER limit would still run the loop once. | |
| 139 | */ | |
| 140 | static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, | |
| 141 | int *stopnow) { | |
| 142 | *stopnow = 0; /* usually, let loops run */ | |
| 143 | if (!tointeger_aux(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */ | |
| 144 | lua_Number n; /* try to convert to float */ | |
| 145 | if (!tonumber(obj, &n)) /* cannot convert to float? */ | |
| 146 | return 0; /* not a number */ | |
| 147 | if (n > 0) { /* if true, float is larger than max integer */ | |
| 148 | *p = LUA_MAXINTEGER; | |
| 149 | if (step < 0) *stopnow = 1; | |
| 150 | } | |
| 151 | else { /* float is smaller than min integer */ | |
| 152 | *p = LUA_MININTEGER; | |
| 153 | if (step >= 0) *stopnow = 1; | |
| 154 | } | |
| 93 | static void callTM (lua_State *L, const TValue *f, const TValue *p1, | |
| 94 | const TValue *p2, TValue *p3, int hasres) { | |
| 95 | ptrdiff_t result = savestack(L, p3); | |
| 96 | setobj2s(L, L->top++, f); /* push function */ | |
| 97 | setobj2s(L, L->top++, p1); /* 1st argument */ | |
| 98 | setobj2s(L, L->top++, p2); /* 2nd argument */ | |
| 99 | if (!hasres) /* no result? 'p3' is third argument */ | |
| 100 | setobj2s(L, L->top++, p3); /* 3rd argument */ | |
| 101 | /* metamethod may yield only when called from Lua code */ | |
| 102 | luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); | |
| 103 | if (hasres) { /* if has result, move it to its place */ | |
| 104 | p3 = restorestack(L, result); | |
| 105 | setobjs2s(L, p3, --L->top); | |
| 155 | 106 | } |
| 156 | return 1; | |
| 157 | 107 | } |
| 158 | 108 | |
| 159 | 109 | |
| 160 | /* | |
| 161 | ** Main function for table access (invoking metamethods if needed). | |
| 162 | ** Compute 'val = t[key]' | |
| 163 | */ | |
| 164 | 110 | void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { |
| 165 | int loop; | |
| 111 | int loop; | |
| 166 | 112 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 167 | 113 | const TValue *tm; |
| 168 | if (ttistable(t)) { /* | |
| 114 | if (ttistable(t)) { /* `t' is a table? */ | |
| 169 | 115 | Table *h = hvalue(t); |
| 170 | 116 | const TValue *res = luaH_get(h, key); /* do a primitive get */ |
| 171 | 117 | if (!ttisnil(res) || /* result is not nil? */ |
| 172 | 118 | (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ |
| 173 | setobj2s(L, val, res); | |
| 119 | setobj2s(L, val, res); | |
| 174 | 120 | return; |
| 175 | 121 | } |
| 176 | /* else will try | |
| 122 | /* else will try the tag method */ | |
| 177 | 123 | } |
| 178 | 124 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) |
| 179 | luaG_typeerror(L, t, "index"); /* no metamethod */ | |
| 180 | if (ttisfunction(tm)) { /* metamethod is a function */ | |
| 181 | luaT_callTM(L, tm, t, key, val, 1); | |
| 125 | luaG_typeerror(L, t, "index"); | |
| 126 | if (ttisfunction(tm)) { | |
| 127 | callTM(L, tm, t, key, val, 1); | |
| 182 | 128 | return; |
| 183 | 129 | } |
| 184 | t = tm; /* else repeat | |
| 130 | t = tm; /* else repeat with 'tm' */ | |
| 185 | 131 | } |
| 186 | luaG_runerror(L, " | |
| 132 | luaG_runerror(L, "loop in gettable"); | |
| 187 | 133 | } |
| 188 | 134 | |
| 189 | 135 | |
| 190 | /* | |
| 191 | ** Main function for table assignment (invoking metamethods if needed). | |
| 192 | ** Compute 't[key] = val' | |
| 193 | */ | |
| 194 | 136 | void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { |
| 195 | int loop; | |
| 137 | int loop; | |
| 196 | 138 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 197 | 139 | const TValue *tm; |
| 198 | if (ttistable(t)) { /* | |
| 140 | if (ttistable(t)) { /* `t' is a table? */ | |
| 199 | 141 | Table *h = hvalue(t); |
| 200 | 142 | TValue *oldval = cast(TValue *, luaH_get(h, key)); |
| 201 | 143 | /* if previous value is not nil, there must be a previous entry |
| 202 | in the table; a metamethod has no relevance */ | |
| 144 | in the table; moreover, a metamethod has no relevance */ | |
| 203 | 145 | if (!ttisnil(oldval) || |
| 204 | 146 | /* previous value is nil; must check the metamethod */ |
| 205 | 147 | ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && |
| r242899 | r242900 | |
| 211 | 153 | /* no metamethod and (now) there is an entry with given key */ |
| 212 | 154 | setobj2t(L, oldval, val); /* assign new value to that entry */ |
| 213 | 155 | invalidateTMcache(h); |
| 214 | luaC_barrierback(L, h, val); | |
| 156 | luaC_barrierback(L, obj2gco(h), val); | |
| 215 | 157 | return; |
| 216 | 158 | } |
| 217 | 159 | /* else will try the metamethod */ |
| r242899 | r242900 | |
| 219 | 161 | else /* not a table; check metamethod */ |
| 220 | 162 | if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) |
| 221 | 163 | luaG_typeerror(L, t, "index"); |
| 222 | /* t | |
| 164 | /* there is a metamethod */ | |
| 223 | 165 | if (ttisfunction(tm)) { |
| 224 | | |
| 166 | callTM(L, tm, t, key, val, 0); | |
| 225 | 167 | return; |
| 226 | 168 | } |
| 227 | t = tm; /* else repeat | |
| 169 | t = tm; /* else repeat with 'tm' */ | |
| 228 | 170 | } |
| 229 | luaG_runerror(L, " | |
| 171 | luaG_runerror(L, "loop in settable"); | |
| 230 | 172 | } |
| 231 | 173 | |
| 232 | 174 | |
| 233 | /* | |
| 234 | ** Compare two strings 'ls' x 'rs', returning an integer smaller-equal- | |
| 235 | ** -larger than zero if 'ls' is smaller-equal-larger than 'rs'. | |
| 236 | ** The code is a little tricky because it allows '\0' in the strings | |
| 237 | ** and it uses 'strcoll' (to respect locales) for each segments | |
| 238 | ** of the strings. | |
| 239 | */ | |
| 175 | static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, | |
| 176 | StkId res, TMS event) { | |
| 177 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ | |
| 178 | if (ttisnil(tm)) | |
| 179 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | |
| 180 | if (ttisnil(tm)) return 0; | |
| 181 | callTM(L, tm, p1, p2, res, 1); | |
| 182 | return 1; | |
| 183 | } | |
| 184 | ||
| 185 | ||
| 186 | static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, | |
| 187 | TMS event) { | |
| 188 | const TValue *tm1 = fasttm(L, mt1, event); | |
| 189 | const TValue *tm2; | |
| 190 | if (tm1 == NULL) return NULL; /* no metamethod */ | |
| 191 | if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ | |
| 192 | tm2 = fasttm(L, mt2, event); | |
| 193 | if (tm2 == NULL) return NULL; /* no metamethod */ | |
| 194 | if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ | |
| 195 | return tm1; | |
| 196 | return NULL; | |
| 197 | } | |
| 198 | ||
| 199 | ||
| 200 | static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, | |
| 201 | TMS event) { | |
| 202 | if (!call_binTM(L, p1, p2, L->top, event)) | |
| 203 | return -1; /* no metamethod */ | |
| 204 | else | |
| 205 | return !l_isfalse(L->top); | |
| 206 | } | |
| 207 | ||
| 208 | ||
| 240 | 209 | static int l_strcmp (const TString *ls, const TString *rs) { |
| 241 | 210 | const char *l = getstr(ls); |
| 242 | size_t ll = ls->len; | |
| 211 | size_t ll = ls->tsv.len; | |
| 243 | 212 | const char *r = getstr(rs); |
| 244 | size_t lr = rs->len; | |
| 245 | for (;;) { /* for each segment */ | |
| 213 | size_t lr = rs->tsv.len; | |
| 214 | for (;;) { | |
| 246 | 215 | int temp = strcoll(l, r); |
| 247 | if (temp != 0) /* not equal? */ | |
| 248 | return temp; /* done */ | |
| 249 | else { /* strings are equal up to a '\0' */ | |
| 250 | size_t len = strlen(l); /* index of first '\0' in both strings */ | |
| 251 | if (len == lr) /* 'rs' is finished? */ | |
| 252 | return (len == ll) ? 0 : 1; /* check 'ls' */ | |
| 253 | else if (len == ll) /* 'ls' is finished? */ | |
| 254 | return -1; /* 'ls' is smaller than 'rs' ('rs' is not finished) */ | |
| 255 | /* both strings longer than 'len'; go on comparing after the '\0' */ | |
| 216 | if (temp != 0) return temp; | |
| 217 | else { /* strings are equal up to a `\0' */ | |
| 218 | size_t len = strlen(l); /* index of first `\0' in both strings */ | |
| 219 | if (len == lr) /* r is finished? */ | |
| 220 | return (len == ll) ? 0 : 1; | |
| 221 | else if (len == ll) /* l is finished? */ | |
| 222 | return -1; /* l is smaller than r (because r is not finished) */ | |
| 223 | /* both strings longer than `len'; go on comparing (after the `\0') */ | |
| 256 | 224 | len++; |
| 257 | 225 | l += len; ll -= len; r += len; lr -= len; |
| 258 | 226 | } |
| r242899 | r242900 | |
| 260 | 228 | } |
| 261 | 229 | |
| 262 | 230 | |
| 263 | /* | |
| 264 | ** Main operation less than; return 'l < r'. | |
| 265 | */ | |
| 266 | 231 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { |
| 267 | 232 | int res; |
| 268 | lua_Number nl, nr; | |
| 269 | if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */ | |
| 270 | return (ivalue(l) < ivalue(r)); | |
| 271 | else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */ | |
| 272 | return luai_numlt(nl, nr); | |
| 273 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | |
| 274 | return l_strcmp(tsvalue(l), tsvalue(r)) < 0; | |
| 275 | else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */ | |
| 276 | luaG_ordererror(L, l, r); /* error */ | |
| 233 | if (ttisnumber(l) && ttisnumber(r)) | |
| 234 | return luai_numlt(L, nvalue(l), nvalue(r)); | |
| 235 | else if (ttisstring(l) && ttisstring(r)) | |
| 236 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; | |
| 237 | else if ((res = call_orderTM(L, l, r, TM_LT)) < 0) | |
| 238 | luaG_ordererror(L, l, r); | |
| 277 | 239 | return res; |
| 278 | 240 | } |
| 279 | 241 | |
| 280 | 242 | |
| 281 | /* | |
| 282 | ** Main operation less than or equal to; return 'l <= r'. | |
| 283 | */ | |
| 284 | 243 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { |
| 285 | 244 | int res; |
| 286 | lua_Number nl, nr; | |
| 287 | if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */ | |
| 288 | return (ivalue(l) <= ivalue(r)); | |
| 289 | else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */ | |
| 290 | return luai_numle(nl, nr); | |
| 291 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | |
| 292 | return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; | |
| 293 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */ | |
| 245 | if (ttisnumber(l) && ttisnumber(r)) | |
| 246 | return luai_numle(L, nvalue(l), nvalue(r)); | |
| 247 | else if (ttisstring(l) && ttisstring(r)) | |
| 248 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; | |
| 249 | else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ | |
| 294 | 250 | return res; |
| 295 | else if ((res = | |
| 251 | else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ | |
| 296 | 252 | luaG_ordererror(L, l, r); |
| 297 | 253 | return !res; |
| 298 | 254 | } |
| 299 | 255 | |
| 300 | 256 | |
| 301 | 257 | /* |
| 302 | ** Main operation for equality of Lua values; return 't1 == t2'. | |
| 303 | ** L == NULL means raw equality (no metamethods) | |
| 258 | ** equality of Lua values. L == NULL means raw equality (no metamethods) | |
| 304 | 259 | */ |
| 305 | int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |
| 260 | int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) { | |
| 306 | 261 | const TValue *tm; |
| 307 | if (ttype(t1) != ttype(t2)) { /* not the same variant? */ | |
| 308 | if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER) | |
| 309 | return 0; /* only numbers can be equal with different variants */ | |
| 310 | else { /* two numbers with different variants */ | |
| 311 | lua_Number n1, n2; /* compare them as floats */ | |
| 312 | lua_assert(ttisnumber(t1) && ttisnumber(t2)); | |
| 313 | cast_void(tofloat(t1, &n1)); cast_void(tofloat(t2, &n2)); | |
| 314 | return luai_numeq(n1, n2); | |
| 315 | } | |
| 316 | } | |
| 317 | /* values have same type and same variant */ | |
| 262 | lua_assert(ttisequal(t1, t2)); | |
| 318 | 263 | switch (ttype(t1)) { |
| 319 | 264 | case LUA_TNIL: return 1; |
| 320 | case LUA_TNUMINT: return (ivalue(t1) == ivalue(t2)); | |
| 321 | case LUA_TNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2)); | |
| 265 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); | |
| 322 | 266 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ |
| 323 | 267 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); |
| 324 | 268 | case LUA_TLCF: return fvalue(t1) == fvalue(t2); |
| 325 | case LUA_TSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2)); | |
| 326 | case LUA_TLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2)); | |
| 269 | case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); | |
| 270 | case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); | |
| 327 | 271 | case LUA_TUSERDATA: { |
| 328 | 272 | if (uvalue(t1) == uvalue(t2)) return 1; |
| 329 | 273 | else if (L == NULL) return 0; |
| 330 | tm = fasttm(L, uvalue(t1)->metatable, TM_EQ); | |
| 331 | if (tm == NULL) | |
| 332 | tm = fasttm(L, uvalue(t2)->metatable, TM_EQ); | |
| 274 | tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); | |
| 333 | 275 | break; /* will try TM */ |
| 334 | 276 | } |
| 335 | 277 | case LUA_TTABLE: { |
| 336 | 278 | if (hvalue(t1) == hvalue(t2)) return 1; |
| 337 | 279 | else if (L == NULL) return 0; |
| 338 | tm = fasttm(L, hvalue(t1)->metatable, TM_EQ); | |
| 339 | if (tm == NULL) | |
| 340 | tm = fasttm(L, hvalue(t2)->metatable, TM_EQ); | |
| 280 | tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); | |
| 341 | 281 | break; /* will try TM */ |
| 342 | 282 | } |
| 343 | 283 | default: |
| 284 | lua_assert(iscollectable(t1)); | |
| 344 | 285 | return gcvalue(t1) == gcvalue(t2); |
| 345 | 286 | } |
| 346 | if (tm == NULL) /* no TM? */ | |
| 347 | return 0; /* objects are different */ | |
| 348 | luaT_callTM(L, tm, t1, t2, L->top, 1); /* call TM */ | |
| 287 | if (tm == NULL) return 0; /* no TM? */ | |
| 288 | callTM(L, tm, t1, t2, L->top, 1); /* call TM */ | |
| 349 | 289 | return !l_isfalse(L->top); |
| 350 | 290 | } |
| 351 | 291 | |
| 352 | 292 | |
| 353 | /* macro used by 'luaV_concat' to ensure that element at 'o' is a string */ | |
| 354 | #define tostring(L,o) \ | |
| 355 | (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) | |
| 356 | ||
| 357 | /* | |
| 358 | ** Main operation for concatenation: concat 'total' values in the stack, | |
| 359 | ** from 'L->top - total' up to 'L->top - 1'. | |
| 360 | */ | |
| 361 | 293 | void luaV_concat (lua_State *L, int total) { |
| 362 | 294 | lua_assert(total >= 2); |
| 363 | 295 | do { |
| 364 | 296 | StkId top = L->top; |
| 365 | 297 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 366 | if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1)) | |
| 367 | luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT); | |
| 298 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { | |
| 299 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) | |
| 300 | luaG_concaterror(L, top-2, top-1); | |
| 301 | } | |
| 368 | 302 | else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ |
| 369 | | |
| 303 | (void)tostring(L, top - 2); /* result is first operand */ | |
| 370 | 304 | else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { |
| 371 | 305 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ |
| 372 | 306 | } |
| r242899 | r242900 | |
| 378 | 312 | /* collect total length */ |
| 379 | 313 | for (i = 1; i < total && tostring(L, top-i-1); i++) { |
| 380 | 314 | size_t l = tsvalue(top-i-1)->len; |
| 381 | if (l >= (MAX_SIZE/sizeof(char)) - tl) | |
| 315 | if (l >= (MAX_SIZET/sizeof(char)) - tl) | |
| 382 | 316 | luaG_runerror(L, "string length overflow"); |
| 383 | 317 | tl += l; |
| 384 | 318 | } |
| 385 | 319 | buffer = luaZ_openspace(L, &G(L)->buff, tl); |
| 386 | 320 | tl = 0; |
| 387 | 321 | n = i; |
| 388 | do { /* co | |
| 322 | do { /* concat all strings */ | |
| 389 | 323 | size_t l = tsvalue(top-i)->len; |
| 390 | 324 | memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); |
| 391 | 325 | tl += l; |
| 392 | 326 | } while (--i > 0); |
| 393 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); | |
| 327 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); | |
| 394 | 328 | } |
| 395 | 329 | total -= n-1; /* got 'n' strings to create 1 new */ |
| 396 | 330 | L->top -= n-1; /* popped 'n' strings and pushed one */ |
| r242899 | r242900 | |
| 398 | 332 | } |
| 399 | 333 | |
| 400 | 334 | |
| 401 | /* | |
| 402 | ** Main operation 'ra' = #rb'. | |
| 403 | */ | |
| 404 | 335 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { |
| 405 | 336 | const TValue *tm; |
| 406 | switch (ttn | |
| 337 | switch (ttypenv(rb)) { | |
| 407 | 338 | case LUA_TTABLE: { |
| 408 | 339 | Table *h = hvalue(rb); |
| 409 | 340 | tm = fasttm(L, h->metatable, TM_LEN); |
| 410 | 341 | if (tm) break; /* metamethod? break switch to call it */ |
| 411 | set | |
| 342 | setnvalue(ra, cast_num(1.0*luaH_getn(h))); /* else primitive len */ | |
| 412 | 343 | return; |
| 413 | 344 | } |
| 414 | 345 | case LUA_TSTRING: { |
| 415 | set | |
| 346 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | |
| 416 | 347 | return; |
| 417 | 348 | } |
| 418 | 349 | default: { /* try metamethod */ |
| r242899 | r242900 | |
| 422 | 353 | break; |
| 423 | 354 | } |
| 424 | 355 | } |
| 425 | | |
| 356 | callTM(L, tm, rb, rb, ra, 1); | |
| 426 | 357 | } |
| 427 | 358 | |
| 428 | 359 | |
| 429 | /* | |
| 430 | ** Integer division; return 'm // n', that is, floor(m/n). | |
| 431 | ** C division truncates its result (rounds towards zero). | |
| 432 | ** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer, | |
| 433 | ** otherwise 'floor(q) == trunc(q) - 1'. | |
| 434 | */ | |
| 435 | lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) { | |
| 436 | if (l_castS2U(n) + 1u <= 1u) { /* special cases: -1 or 0 */ | |
| 437 | if (n == 0) | |
| 438 | luaG_runerror(L, "attempt to divide by zero"); | |
| 439 | return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */ | |
| 360 | void luaV_arith (lua_State *L, StkId ra, const TValue *rb, | |
| 361 | const TValue *rc, TMS op) { | |
| 362 | TValue tempb, tempc; | |
| 363 | const TValue *b, *c; | |
| 364 | if ((b = luaV_tonumber(rb, &tempb)) != NULL && | |
| 365 | (c = luaV_tonumber(rc, &tempc)) != NULL) { | |
| 366 | lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c)); | |
| 367 | setnvalue(ra, res); | |
| 440 | 368 | } |
| 441 | else { | |
| 442 | lua_Integer q = m / n; /* perform C division */ | |
| 443 | if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */ | |
| 444 | q -= 1; /* correct result for different rounding */ | |
| 445 | return q; | |
| 446 | } | |
| 369 | else if (!call_binTM(L, rb, rc, ra, op)) | |
| 370 | luaG_aritherror(L, rb, rc); | |
| 447 | 371 | } |
| 448 | 372 | |
| 449 | 373 | |
| 450 | 374 | /* |
| 451 | ** Integer modulus; return 'm % n'. (Assume that C '%' with | |
| 452 | ** negative operands follows C99 behavior. See previous comment | |
| 453 | ** about luaV_div.) | |
| 454 | */ | |
| 455 | lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) { | |
| 456 | if (l_castS2U(n) + 1u <= 1u) { /* special cases: -1 or 0 */ | |
| 457 | if (n == 0) | |
| 458 | luaG_runerror(L, "attempt to perform 'n%%0'"); | |
| 459 | return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ | |
| 460 | } | |
| 461 | else { | |
| 462 | lua_Integer r = m % n; | |
| 463 | if (r != 0 && (m ^ n) < 0) /* 'm/n' would be non-integer negative? */ | |
| 464 | r += n; /* correct result for different rounding */ | |
| 465 | return r; | |
| 466 | } | |
| 467 | } | |
| 468 | ||
| 469 | ||
| 470 | /* number of bits in an integer */ | |
| 471 | #define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) | |
| 472 | ||
| 473 | /* | |
| 474 | ** Shift left operation. (Shift right just negates 'y'.) | |
| 475 | */ | |
| 476 | lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { | |
| 477 | if (y < 0) { /* shift right? */ | |
| 478 | if (y <= -NBITS) return 0; | |
| 479 | else return intop(>>, x, -y); | |
| 480 | } | |
| 481 | else { /* shift left */ | |
| 482 | if (y >= NBITS) return 0; | |
| 483 | else return intop(<<, x, y); | |
| 484 | } | |
| 485 | } | |
| 486 | ||
| 487 | ||
| 488 | /* | |
| 489 | 375 | ** check whether cached closure in prototype 'p' may be reused, that is, |
| 490 | 376 | ** whether there is a cached closure with the same upvalues needed by |
| 491 | 377 | ** new closure to be created. |
| 492 | 378 | */ |
| 493 | static LClosure *getcached (Proto *p, UpVal **encup, StkId base) { | |
| 494 | LClosure *c = p->cache; | |
| 379 | static Closure *getcached (Proto *p, UpVal **encup, StkId base) { | |
| 380 | Closure *c = p->cache; | |
| 495 | 381 | if (c != NULL) { /* is there a cached closure? */ |
| 496 | 382 | int nup = p->sizeupvalues; |
| 497 | 383 | Upvaldesc *uv = p->upvalues; |
| 498 | 384 | int i; |
| 499 | 385 | for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ |
| 500 | 386 | TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; |
| 501 | if (c->upvals[i]->v != v) | |
| 387 | if (c->l.upvals[i]->v != v) | |
| 502 | 388 | return NULL; /* wrong upvalue; cannot reuse closure */ |
| 503 | 389 | } |
| 504 | 390 | } |
| r242899 | r242900 | |
| 508 | 394 | |
| 509 | 395 | /* |
| 510 | 396 | ** create a new Lua closure, push it in the stack, and initialize |
| 511 | ** its upvalues. Note that the closure is not cached if prototype is | |
| 512 | ** already black (which means that 'cache' was already cleared by the | |
| 513 | ** GC). | |
| 397 | ** its upvalues. Note that the call to 'luaC_barrierproto' must come | |
| 398 | ** before the assignment to 'p->cache', as the function needs the | |
| 399 | ** original value of that field. | |
| 514 | 400 | */ |
| 515 | 401 | static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, |
| 516 | 402 | StkId ra) { |
| 517 | 403 | int nup = p->sizeupvalues; |
| 518 | 404 | Upvaldesc *uv = p->upvalues; |
| 519 | 405 | int i; |
| 520 | LClosure *ncl = luaF_newLclosure(L, nup); | |
| 521 | ncl->p = p; | |
| 406 | Closure *ncl = luaF_newLclosure(L, nup); | |
| 407 | ncl->l.p = p; | |
| 522 | 408 | setclLvalue(L, ra, ncl); /* anchor new closure in stack */ |
| 523 | 409 | for (i = 0; i < nup; i++) { /* fill in its upvalues */ |
| 524 | 410 | if (uv[i].instack) /* upvalue refers to local variable? */ |
| 525 | ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx); | |
| 411 | ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); | |
| 526 | 412 | else /* get upvalue from enclosing function */ |
| 527 | ncl->upvals[i] = encup[uv[i].idx]; | |
| 528 | ncl->upvals[i]->refcount++; | |
| 529 | /* new closure is white, so we do not need a barrier here */ | |
| 413 | ncl->l.upvals[i] = encup[uv[i].idx]; | |
| 530 | 414 | } |
| 531 | if (!isblack(p)) /* cache will not break GC invariant? */ | |
| 532 | p->cache = ncl; /* save it on cache for reuse */ | |
| 415 | luaC_barrierproto(L, p, ncl); | |
| 416 | p->cache = ncl; /* save it on cache for reuse */ | |
| 533 | 417 | } |
| 534 | 418 | |
| 535 | 419 | |
| r242899 | r242900 | |
| 542 | 426 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ |
| 543 | 427 | OpCode op = GET_OPCODE(inst); |
| 544 | 428 | switch (op) { /* finish its execution */ |
| 545 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: | |
| 546 | case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: | |
| 547 | case OP_MOD: case OP_POW: | |
| 548 | case OP_UNM: case OP_BNOT: case OP_LEN: | |
| 429 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: | |
| 430 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | |
| 549 | 431 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { |
| 550 | 432 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
| 551 | 433 | break; |
| r242899 | r242900 | |
| 564 | 446 | break; |
| 565 | 447 | } |
| 566 | 448 | case OP_CONCAT: { |
| 567 | StkId top = L->top - 1; /* top when ' | |
| 449 | StkId top = L->top - 1; /* top when 'call_binTM' was called */ | |
| 568 | 450 | int b = GETARG_B(inst); /* first element to concatenate */ |
| 569 | 451 | int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ |
| 570 | 452 | setobj2s(L, top - 2, top); /* put TM result in proper position */ |
| r242899 | r242900 | |
| 595 | 477 | |
| 596 | 478 | |
| 597 | 479 | |
| 598 | ||
| 599 | 480 | /* |
| 600 | ** {================================================================== | |
| 601 | ** Function 'luaV_execute': main interpreter loop | |
| 602 | ** =================================================================== | |
| 481 | ** some macros for common tasks in `luaV_execute' | |
| 603 | 482 | */ |
| 604 | 483 | |
| 605 | ||
| 606 | /* | |
| 607 | ** some macros for common tasks in 'luaV_execute' | |
| 608 | */ | |
| 609 | ||
| 610 | 484 | #if !defined luai_runtimecheck |
| 611 | 485 | #define luai_runtimecheck(L, c) /* void */ |
| 612 | 486 | #endif |
| r242899 | r242900 | |
| 643 | 517 | luai_threadyield(L); ) |
| 644 | 518 | |
| 645 | 519 | |
| 520 | #define arith_op(op,tm) { \ | |
| 521 | TValue *rb = RKB(i); \ | |
| 522 | TValue *rc = RKC(i); \ | |
| 523 | if (ttisnumber(rb) && ttisnumber(rc)) { \ | |
| 524 | lua_Number nb = nvalue(rb), nc = nvalue(rc); \ | |
| 525 | setnvalue(ra, op(L, nb, nc)); \ | |
| 526 | } \ | |
| 527 | else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } | |
| 528 | ||
| 529 | ||
| 646 | 530 | #define vmdispatch(o) switch(o) |
| 647 | #define vmcase(l) case l: | |
| 648 | #define vmbreak break | |
| 531 | #define vmcase(l,b) case l: {b} break; | |
| 532 | #define vmcasenb(l,b) case l: {b} /* nb = no break */ | |
| 649 | 533 | |
| 650 | 534 | void luaV_execute (lua_State *L) { |
| 651 | 535 | CallInfo *ci = L->ci; |
| r242899 | r242900 | |
| 663 | 547 | StkId ra; |
| 664 | 548 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && |
| 665 | 549 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
| 666 | Protect( | |
| 550 | Protect(traceexec(L)); | |
| 667 | 551 | } |
| 668 | /* WARNING: several calls may realloc the stack and invalidate | |
| 552 | /* WARNING: several calls may realloc the stack and invalidate `ra' */ | |
| 669 | 553 | ra = RA(i); |
| 670 | 554 | lua_assert(base == ci->u.l.base); |
| 671 | 555 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); |
| 672 | 556 | vmdispatch (GET_OPCODE(i)) { |
| 673 | vmcase(OP_MOVE | |
| 557 | vmcase(OP_MOVE, | |
| 674 | 558 | setobjs2s(L, ra, RB(i)); |
| 675 | vmbreak; | |
| 676 | } | |
| 677 | vmcase(OP_LOADK) { | |
| 559 | ) | |
| 560 | vmcase(OP_LOADK, | |
| 678 | 561 | TValue *rb = k + GETARG_Bx(i); |
| 679 | 562 | setobj2s(L, ra, rb); |
| 680 | vmbreak; | |
| 681 | } | |
| 682 | vmcase(OP_LOADKX) { | |
| 563 | ) | |
| 564 | vmcase(OP_LOADKX, | |
| 683 | 565 | TValue *rb; |
| 684 | 566 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); |
| 685 | 567 | rb = k + GETARG_Ax(*ci->u.l.savedpc++); |
| 686 | 568 | setobj2s(L, ra, rb); |
| 687 | vmbreak; | |
| 688 | } | |
| 689 | vmcase(OP_LOADBOOL) { | |
| 569 | ) | |
| 570 | vmcase(OP_LOADBOOL, | |
| 690 | 571 | setbvalue(ra, GETARG_B(i)); |
| 691 | 572 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ |
| 692 | vmbreak; | |
| 693 | } | |
| 694 | vmcase(OP_LOADNIL) { | |
| 573 | ) | |
| 574 | vmcase(OP_LOADNIL, | |
| 695 | 575 | int b = GETARG_B(i); |
| 696 | 576 | do { |
| 697 | 577 | setnilvalue(ra++); |
| 698 | 578 | } while (b--); |
| 699 | vmbreak; | |
| 700 | } | |
| 701 | vmcase(OP_GETUPVAL) { | |
| 579 | ) | |
| 580 | vmcase(OP_GETUPVAL, | |
| 702 | 581 | int b = GETARG_B(i); |
| 703 | 582 | setobj2s(L, ra, cl->upvals[b]->v); |
| 704 | vmbreak; | |
| 705 | } | |
| 706 | vmcase(OP_GETTABUP) { | |
| 583 | ) | |
| 584 | vmcase(OP_GETTABUP, | |
| 707 | 585 | int b = GETARG_B(i); |
| 708 | 586 | Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); |
| 709 | vmbreak; | |
| 710 | } | |
| 711 | vmcase(OP_GETTABLE) { | |
| 587 | ) | |
| 588 | vmcase(OP_GETTABLE, | |
| 712 | 589 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); |
| 713 | vmbreak; | |
| 714 | } | |
| 715 | vmcase(OP_SETTABUP) { | |
| 590 | ) | |
| 591 | vmcase(OP_SETTABUP, | |
| 716 | 592 | int a = GETARG_A(i); |
| 717 | 593 | Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); |
| 718 | vmbreak; | |
| 719 | } | |
| 720 | vmcase(OP_SETUPVAL) { | |
| 594 | ) | |
| 595 | vmcase(OP_SETUPVAL, | |
| 721 | 596 | UpVal *uv = cl->upvals[GETARG_B(i)]; |
| 722 | 597 | setobj(L, uv->v, ra); |
| 723 | luaC_upvalbarrier(L, uv); | |
| 724 | vmbreak; | |
| 725 | } | |
| 726 | vmcase(OP_SETTABLE) { | |
| 598 | luaC_barrier(L, uv, ra); | |
| 599 | ) | |
| 600 | vmcase(OP_SETTABLE, | |
| 727 | 601 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); |
| 728 | vmbreak; | |
| 729 | } | |
| 730 | vmcase(OP_NEWTABLE) { | |
| 602 | ) | |
| 603 | vmcase(OP_NEWTABLE, | |
| 731 | 604 | int b = GETARG_B(i); |
| 732 | 605 | int c = GETARG_C(i); |
| 733 | 606 | Table *t = luaH_new(L); |
| r242899 | r242900 | |
| 735 | 608 | if (b != 0 || c != 0) |
| 736 | 609 | luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); |
| 737 | 610 | checkGC(L, ra + 1); |
| 738 | vmbreak; | |
| 739 | } | |
| 740 | vmcase(OP_SELF) { | |
| 611 | ) | |
| 612 | vmcase(OP_SELF, | |
| 741 | 613 | StkId rb = RB(i); |
| 742 | 614 | setobjs2s(L, ra+1, rb); |
| 743 | 615 | Protect(luaV_gettable(L, rb, RKC(i), ra)); |
| 744 | vmbreak; | |
| 745 | } | |
| 746 | vmcase(OP_ADD) { | |
| 747 | TValue *rb = RKB(i); | |
| 748 | TValue *rc = RKC(i); | |
| 749 | lua_Number nb; lua_Number nc; | |
| 750 | if (ttisinteger(rb) && ttisinteger(rc)) { | |
| 751 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | |
| 752 | setivalue(ra, intop(+, ib, ic)); | |
| 753 | } | |
| 754 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | |
| 755 | setfltvalue(ra, luai_numadd(L, nb, nc)); | |
| 756 | } | |
| 757 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); } | |
| 758 | vmbreak; | |
| 759 | } | |
| 760 | vmcase(OP_SUB) { | |
| 761 | TValue *rb = RKB(i); | |
| 762 | TValue *rc = RKC(i); | |
| 763 | lua_Number nb; lua_Number nc; | |
| 764 | if (ttisinteger(rb) && ttisinteger(rc)) { | |
| 765 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | |
| 766 | setivalue(ra, intop(-, ib, ic)); | |
| 767 | } | |
| 768 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | |
| 769 | setfltvalue(ra, luai_numsub(L, nb, nc)); | |
| 770 | } | |
| 771 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); } | |
| 772 | vmbreak; | |
| 773 | } | |
| 774 | vmcase(OP_MUL) { | |
| 775 | TValue *rb = RKB(i); | |
| 776 | TValue *rc = RKC(i); | |
| 777 | lua_Number nb; lua_Number nc; | |
| 778 | if (ttisinteger(rb) && ttisinteger(rc)) { | |
| 779 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | |
| 780 | setivalue(ra, intop(*, ib, ic)); | |
| 781 | } | |
| 782 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | |
| 783 | setfltvalue(ra, luai_nummul(L, nb, nc)); | |
| 784 | } | |
| 785 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); } | |
| 786 | vmbreak; | |
| 787 | } | |
| 788 | vmcase(OP_DIV) { /* float division (always with floats) */ | |
| 789 | TValue *rb = RKB(i); | |
| 790 | TValue *rc = RKC(i); | |
| 791 | lua_Number nb; lua_Number nc; | |
| 792 | if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | |
| 793 | setfltvalue(ra, luai_numdiv(L, nb, nc)); | |
| 794 | } | |
| 795 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); } | |
| 796 | vmbreak; | |
| 797 | } | |
| 798 | vmcase(OP_BAND) { | |
| 799 | TValue *rb = RKB(i); | |
| 800 | TValue *rc = RKC(i); | |
| 801 | lua_Integer ib; lua_Integer ic; | |
| 802 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | |
| 803 | setivalue(ra, intop(&, ib, ic)); | |
| 804 | } | |
| 805 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); } | |
| 806 | vmbreak; | |
| 807 | } | |
| 808 | vmcase(OP_BOR) { | |
| 809 | TValue *rb = RKB(i); | |
| 810 | TValue *rc = RKC(i); | |
| 811 | lua_Integer ib; lua_Integer ic; | |
| 812 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | |
| 813 | setivalue(ra, intop(|, ib, ic)); | |
| 814 | } | |
| 815 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); } | |
| 816 | vmbreak; | |
| 817 | } | |
| 818 | vmcase(OP_BXOR) { | |
| 819 | TValue *rb = RKB(i); | |
| 820 | TValue *rc = RKC(i); | |
| 821 | lua_Integer ib; lua_Integer ic; | |
| 822 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | |
| 823 | setivalue(ra, intop(^, ib, ic)); | |
| 824 | } | |
| 825 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } | |
| 826 | vmbreak; | |
| 827 | } | |
| 828 | vmcase(OP_SHL) { | |
| 829 | TValue *rb = RKB(i); | |
| 830 | TValue *rc = RKC(i); | |
| 831 | lua_Integer ib; lua_Integer ic; | |
| 832 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | |
| 833 | setivalue(ra, luaV_shiftl(ib, ic)); | |
| 834 | } | |
| 835 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } | |
| 836 | vmbreak; | |
| 837 | } | |
| 838 | vmcase(OP_SHR) { | |
| 839 | TValue *rb = RKB(i); | |
| 840 | TValue *rc = RKC(i); | |
| 841 | lua_Integer ib; lua_Integer ic; | |
| 842 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | |
| 843 | setivalue(ra, luaV_shiftl(ib, -ic)); | |
| 844 | } | |
| 845 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } | |
| 846 | vmbreak; | |
| 847 | } | |
| 848 | vmcase(OP_MOD) { | |
| 849 | TValue *rb = RKB(i); | |
| 850 | TValue *rc = RKC(i); | |
| 851 | lua_Number nb; lua_Number nc; | |
| 852 | if (ttisinteger(rb) && ttisinteger(rc)) { | |
| 853 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | |
| 854 | setivalue(ra, luaV_mod(L, ib, ic)); | |
| 855 | } | |
| 856 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | |
| 857 | lua_Number m; | |
| 858 | luai_nummod(L, nb, nc, m); | |
| 859 | setfltvalue(ra, m); | |
| 860 | } | |
| 861 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); } | |
| 862 | vmbreak; | |
| 863 | } | |
| 864 | vmcase(OP_IDIV) { /* floor division */ | |
| 865 | TValue *rb = RKB(i); | |
| 866 | TValue *rc = RKC(i); | |
| 867 | lua_Number nb; lua_Number nc; | |
| 868 | if (ttisinteger(rb) && ttisinteger(rc)) { | |
| 869 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); | |
| 870 | setivalue(ra, luaV_div(L, ib, ic)); | |
| 871 | } | |
| 872 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | |
| 873 | setfltvalue(ra, luai_numidiv(L, nb, nc)); | |
| 874 | } | |
| 875 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); } | |
| 876 | vmbreak; | |
| 877 | } | |
| 878 | vmcase(OP_POW) { | |
| 879 | TValue *rb = RKB(i); | |
| 880 | TValue *rc = RKC(i); | |
| 881 | lua_Number nb; lua_Number nc; | |
| 882 | if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | |
| 883 | setfltvalue(ra, luai_numpow(L, nb, nc)); | |
| 884 | } | |
| 885 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); } | |
| 886 | vmbreak; | |
| 887 | } | |
| 888 | vmcase(OP_UNM) { | |
| 616 | ) | |
| 617 | vmcase(OP_ADD, | |
| 618 | arith_op(luai_numadd, TM_ADD); | |
| 619 | ) | |
| 620 | vmcase(OP_SUB, | |
| 621 | arith_op(luai_numsub, TM_SUB); | |
| 622 | ) | |
| 623 | vmcase(OP_MUL, | |
| 624 | arith_op(luai_nummul, TM_MUL); | |
| 625 | ) | |
| 626 | vmcase(OP_DIV, | |
| 627 | arith_op(luai_numdiv, TM_DIV); | |
| 628 | ) | |
| 629 | vmcase(OP_MOD, | |
| 630 | arith_op(luai_nummod, TM_MOD); | |
| 631 | ) | |
| 632 | vmcase(OP_POW, | |
| 633 | arith_op(luai_numpow, TM_POW); | |
| 634 | ) | |
| 635 | vmcase(OP_UNM, | |
| 889 | 636 | TValue *rb = RB(i); |
| 890 | lua_Number nb; | |
| 891 | if (ttisinteger(rb)) { | |
| 892 | lua_Integer ib = ivalue(rb); | |
| 893 | setivalue(ra, intop(-, 0, ib)); | |
| 637 | if (ttisnumber(rb)) { | |
| 638 | lua_Number nb = nvalue(rb); | |
| 639 | setnvalue(ra, luai_numunm(L, nb)); | |
| 894 | 640 | } |
| 895 | else if (tonumber(rb, &nb)) { | |
| 896 | setfltvalue(ra, luai_numunm(L, nb)); | |
| 897 | } | |
| 898 | 641 | else { |
| 899 | Protect(lua | |
| 642 | Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); | |
| 900 | 643 | } |
| 901 | vmbreak; | |
| 902 | } | |
| 903 | vmcase(OP_BNOT) { | |
| 644 | ) | |
| 645 | vmcase(OP_NOT, | |
| 904 | 646 | TValue *rb = RB(i); |
| 905 | lua_Integer ib; | |
| 906 | if (tointeger(rb, &ib)) { | |
| 907 | setivalue(ra, intop(^, ~l_castS2U(0), ib)); | |
| 908 | } | |
| 909 | else { | |
| 910 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); | |
| 911 | } | |
| 912 | vmbreak; | |
| 913 | } | |
| 914 | vmcase(OP_NOT) { | |
| 915 | TValue *rb = RB(i); | |
| 916 | 647 | int res = l_isfalse(rb); /* next assignment may change this value */ |
| 917 | 648 | setbvalue(ra, res); |
| 918 | vmbreak; | |
| 919 | } | |
| 920 | vmcase(OP_LEN) { | |
| 649 | ) | |
| 650 | vmcase(OP_LEN, | |
| 921 | 651 | Protect(luaV_objlen(L, ra, RB(i))); |
| 922 | vmbreak; | |
| 923 | } | |
| 924 | vmcase(OP_CONCAT) { | |
| 652 | ) | |
| 653 | vmcase(OP_CONCAT, | |
| 925 | 654 | int b = GETARG_B(i); |
| 926 | 655 | int c = GETARG_C(i); |
| 927 | 656 | StkId rb; |
| r242899 | r242900 | |
| 932 | 661 | setobjs2s(L, ra, rb); |
| 933 | 662 | checkGC(L, (ra >= rb ? ra + 1 : rb)); |
| 934 | 663 | L->top = ci->top; /* restore top */ |
| 935 | vmbreak; | |
| 936 | } | |
| 937 | vmcase(OP_JMP) { | |
| 664 | ) | |
| 665 | vmcase(OP_JMP, | |
| 938 | 666 | dojump(ci, i, 0); |
| 939 | vmbreak; | |
| 940 | } | |
| 941 | vmcase(OP_EQ) { | |
| 667 | ) | |
| 668 | vmcase(OP_EQ, | |
| 942 | 669 | TValue *rb = RKB(i); |
| 943 | 670 | TValue *rc = RKC(i); |
| 944 | 671 | Protect( |
| 945 | if (cast_int( | |
| 672 | if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i)) | |
| 946 | 673 | ci->u.l.savedpc++; |
| 947 | 674 | else |
| 948 | 675 | donextjump(ci); |
| 949 | 676 | ) |
| 950 | vmbreak; | |
| 951 | } | |
| 952 | vmcase(OP_LT) { | |
| 677 | ) | |
| 678 | vmcase(OP_LT, | |
| 953 | 679 | Protect( |
| 954 | 680 | if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) |
| 955 | 681 | ci->u.l.savedpc++; |
| 956 | 682 | else |
| 957 | 683 | donextjump(ci); |
| 958 | 684 | ) |
| 959 | vmbreak; | |
| 960 | } | |
| 961 | vmcase(OP_LE) { | |
| 685 | ) | |
| 686 | vmcase(OP_LE, | |
| 962 | 687 | Protect( |
| 963 | 688 | if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) |
| 964 | 689 | ci->u.l.savedpc++; |
| 965 | 690 | else |
| 966 | 691 | donextjump(ci); |
| 967 | 692 | ) |
| 968 | vmbreak; | |
| 969 | } | |
| 970 | vmcase(OP_TEST) { | |
| 693 | ) | |
| 694 | vmcase(OP_TEST, | |
| 971 | 695 | if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) |
| 972 | 696 | ci->u.l.savedpc++; |
| 973 | 697 | else |
| 974 | 698 | donextjump(ci); |
| 975 | vmbreak; | |
| 976 | } | |
| 977 | vmcase(OP_TESTSET) { | |
| 699 | ) | |
| 700 | vmcase(OP_TESTSET, | |
| 978 | 701 | TValue *rb = RB(i); |
| 979 | 702 | if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) |
| 980 | 703 | ci->u.l.savedpc++; |
| r242899 | r242900 | |
| 982 | 705 | setobjs2s(L, ra, rb); |
| 983 | 706 | donextjump(ci); |
| 984 | 707 | } |
| 985 | vmbreak; | |
| 986 | } | |
| 987 | vmcase(OP_CALL) { | |
| 708 | ) | |
| 709 | vmcase(OP_CALL, | |
| 988 | 710 | int b = GETARG_B(i); |
| 989 | 711 | int nresults = GETARG_C(i) - 1; |
| 990 | 712 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| r242899 | r242900 | |
| 997 | 719 | ci->callstatus |= CIST_REENTRY; |
| 998 | 720 | goto newframe; /* restart luaV_execute over new Lua function */ |
| 999 | 721 | } |
| 1000 | vmbreak; | |
| 1001 | } | |
| 1002 | vmcase(OP_TAILCALL) { | |
| 722 | ) | |
| 723 | vmcase(OP_TAILCALL, | |
| 1003 | 724 | int b = GETARG_B(i); |
| 1004 | 725 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 1005 | 726 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
| r242899 | r242900 | |
| 1027 | 748 | lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); |
| 1028 | 749 | goto newframe; /* restart luaV_execute over new Lua function */ |
| 1029 | 750 | } |
| 1030 | vmbreak; | |
| 1031 | } | |
| 1032 | vmcase(OP_RETURN) { | |
| 751 | ) | |
| 752 | vmcasenb(OP_RETURN, | |
| 1033 | 753 | int b = GETARG_B(i); |
| 1034 | 754 | if (b != 0) L->top = ra+b-1; |
| 1035 | 755 | if (cl->p->sizep > 0) luaF_close(L, base); |
| r242899 | r242900 | |
| 1043 | 763 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); |
| 1044 | 764 | goto newframe; /* restart luaV_execute over new Lua function */ |
| 1045 | 765 | } |
| 1046 | } | |
| 1047 | vmcase(OP_FORLOOP) { | |
| 1048 | if (ttisinteger(ra)) { /* integer loop? */ | |
| 1049 | lua_Integer step = ivalue(ra + 2); | |
| 1050 | lua_Integer idx = ivalue(ra) + step; /* increment index */ | |
| 1051 | lua_Integer limit = ivalue(ra + 1); | |
| 1052 | if ((0 < step) ? (idx <= limit) : (limit <= idx)) { | |
| 1053 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | |
| 1054 | setivalue(ra, idx); /* update internal index... */ | |
| 1055 | setivalue(ra + 3, idx); /* ...and external index */ | |
| 1056 | } | |
| 766 | ) | |
| 767 | vmcase(OP_FORLOOP, | |
| 768 | lua_Number step = nvalue(ra+2); | |
| 769 | lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ | |
| 770 | lua_Number limit = nvalue(ra+1); | |
| 771 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) | |
| 772 | : luai_numle(L, limit, idx)) { | |
| 773 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | |
| 774 | setnvalue(ra, idx); /* update internal index... */ | |
| 775 | setnvalue(ra+3, idx); /* ...and external index */ | |
| 1057 | 776 | } |
| 1058 | else { /* floating loop */ | |
| 1059 | lua_Number step = fltvalue(ra + 2); | |
| 1060 | lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */ | |
| 1061 | lua_Number limit = fltvalue(ra + 1); | |
| 1062 | if (luai_numlt(0, step) ? luai_numle(idx, limit) | |
| 1063 | : luai_numle(limit, idx)) { | |
| 1064 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | |
| 1065 | setfltvalue(ra, idx); /* update internal index... */ | |
| 1066 | setfltvalue(ra + 3, idx); /* ...and external index */ | |
| 1067 | } | |
| 1068 | } | |
| 1069 | vmbreak; | |
| 1070 | } | |
| 1071 | vmcase(OP_FORPREP) { | |
| 1072 | TValue *init = ra; | |
| 1073 | TValue *plimit = ra + 1; | |
| 1074 | TValue *pstep = ra + 2; | |
| 1075 | lua_Integer ilimit; | |
| 1076 | int stopnow; | |
| 1077 | if (ttisinteger(init) && ttisinteger(pstep) && | |
| 1078 | forlimit(plimit, &ilimit, ivalue(pstep), &stopnow)) { | |
| 1079 | /* all values are integer */ | |
| 1080 | lua_Integer initv = (stopnow ? 0 : ivalue(init)); | |
| 1081 | setivalue(plimit, ilimit); | |
| 1082 | setivalue(init, initv - ivalue(pstep)); | |
| 1083 | } | |
| 1084 | else { /* try making all values floats */ | |
| 1085 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; | |
| 1086 | if (!tonumber(plimit, &nlimit)) | |
| 1087 | luaG_runerror(L, "'for' limit must be a number"); | |
| 1088 | setfltvalue(plimit, nlimit); | |
| 1089 | if (!tonumber(pstep, &nstep)) | |
| 1090 | luaG_runerror(L, "'for' step must be a number"); | |
| 1091 | setfltvalue(pstep, nstep); | |
| 1092 | if (!tonumber(init, &ninit)) | |
| 1093 | luaG_runerror(L, "'for' initial value must be a number"); | |
| 1094 | setfltvalue(init, luai_numsub(L, ninit, nstep)); | |
| 1095 | } | |
| 777 | ) | |
| 778 | vmcase(OP_FORPREP, | |
| 779 | const TValue *init = ra; | |
| 780 | const TValue *plimit = ra+1; | |
| 781 | const TValue *pstep = ra+2; | |
| 782 | if (!tonumber(init, ra)) | |
| 783 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); | |
| 784 | else if (!tonumber(plimit, ra+1)) | |
| 785 | luaG_runerror(L, LUA_QL("for") " limit must be a number"); | |
| 786 | else if (!tonumber(pstep, ra+2)) | |
| 787 | luaG_runerror(L, LUA_QL("for") " step must be a number"); | |
| 788 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); | |
| 1096 | 789 | ci->u.l.savedpc += GETARG_sBx(i); |
| 1097 | vmbreak; | |
| 1098 | } | |
| 1099 | vmcase(OP_TFORCALL) { | |
| 790 | ) | |
| 791 | vmcasenb(OP_TFORCALL, | |
| 1100 | 792 | StkId cb = ra + 3; /* call base */ |
| 1101 | 793 | setobjs2s(L, cb+2, ra+2); |
| 1102 | 794 | setobjs2s(L, cb+1, ra+1); |
| r242899 | r242900 | |
| 1108 | 800 | ra = RA(i); |
| 1109 | 801 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
| 1110 | 802 | goto l_tforloop; |
| 1111 | } | |
| 1112 | vmcase(OP_TFORLOOP) { | |
| 803 | ) | |
| 804 | vmcase(OP_TFORLOOP, | |
| 1113 | 805 | l_tforloop: |
| 1114 | 806 | if (!ttisnil(ra + 1)) { /* continue loop? */ |
| 1115 | 807 | setobjs2s(L, ra, ra + 1); /* save control variable */ |
| 1116 | 808 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ |
| 1117 | 809 | } |
| 1118 | vmbreak; | |
| 1119 | } | |
| 1120 | vmcase(OP_SETLIST) { | |
| 810 | ) | |
| 811 | vmcase(OP_SETLIST, | |
| 1121 | 812 | int n = GETARG_B(i); |
| 1122 | 813 | int c = GETARG_C(i); |
| 1123 | | |
| 814 | int last; | |
| 1124 | 815 | Table *h; |
| 1125 | 816 | if (n == 0) n = cast_int(L->top - ra) - 1; |
| 1126 | 817 | if (c == 0) { |
| r242899 | r242900 | |
| 1135 | 826 | for (; n > 0; n--) { |
| 1136 | 827 | TValue *val = ra+n; |
| 1137 | 828 | luaH_setint(L, h, last--, val); |
| 1138 | luaC_barrierback(L, h, val); | |
| 829 | luaC_barrierback(L, obj2gco(h), val); | |
| 1139 | 830 | } |
| 1140 | 831 | L->top = ci->top; /* correct top (in case of previous open call) */ |
| 1141 | vmbreak; | |
| 1142 | } | |
| 1143 | vmcase(OP_CLOSURE) { | |
| 832 | ) | |
| 833 | vmcase(OP_CLOSURE, | |
| 1144 | 834 | Proto *p = cl->p->p[GETARG_Bx(i)]; |
| 1145 | | |
| 835 | Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ | |
| 1146 | 836 | if (ncl == NULL) /* no match? */ |
| 1147 | 837 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ |
| 1148 | 838 | else |
| 1149 | 839 | setclLvalue(L, ra, ncl); /* push cashed closure */ |
| 1150 | 840 | checkGC(L, ra + 1); |
| 1151 | vmbreak; | |
| 1152 | } | |
| 1153 | vmcase(OP_VARARG) { | |
| 841 | ) | |
| 842 | vmcase(OP_VARARG, | |
| 1154 | 843 | int b = GETARG_B(i) - 1; |
| 1155 | 844 | int j; |
| 1156 | 845 | int n = cast_int(base - ci->func) - cl->p->numparams - 1; |
| r242899 | r242900 | |
| 1168 | 857 | setnilvalue(ra + j); |
| 1169 | 858 | } |
| 1170 | 859 | } |
| 1171 | vmbreak; | |
| 1172 | } | |
| 1173 | vmcase(OP_EXTRAARG) { | |
| 860 | ) | |
| 861 | vmcase(OP_EXTRAARG, | |
| 1174 | 862 | lua_assert(0); |
| 1175 | vmbreak; | |
| 1176 | } | |
| 863 | ) | |
| 1177 | 864 | } |
| 1178 | 865 | } |
| 1179 | 866 | } |
| 1180 | 867 | |
| 1181 | /* }================================================================== */ | |
| 1182 |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lvm.h,v 2. | |
| 2 | ** $Id: lvm.h,v 2.18.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 13 | 13 | #include "ltm.h" |
| 14 | 14 | |
| 15 | 15 | |
| 16 | #if !defined(LUA_NOCVTN2S) | |
| 17 | #define cvt2str(o) ttisnumber(o) | |
| 18 | #else | |
| 19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ | |
| 20 | #endif | |
| 16 | #define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o))) | |
| 21 | 17 | |
| 18 | #define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) | |
| 22 | 19 | |
| 23 | #if !defined(LUA_NOCVTS2N) | |
| 24 | #define cvt2num(o) ttisstring(o) | |
| 25 | #else | |
| 26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ | |
| 27 | #endif | |
| 20 | #define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) | |
| 28 | 21 | |
| 22 | #define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2) | |
| 29 | 23 | |
| 30 | #define tonumber(o,n) \ | |
| 31 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) | |
| 32 | 24 | |
| 33 | #define tointeger(o,i) \ | |
| 34 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger_(o,i)) | |
| 25 | /* not to called directly */ | |
| 26 | LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2); | |
| 35 | 27 | |
| 36 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) | |
| 37 | 28 | |
| 38 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) | |
| 39 | ||
| 40 | ||
| 41 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); | |
| 42 | 29 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); |
| 43 | 30 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); |
| 44 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); | |
| 45 | LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p); | |
| 31 | LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); | |
| 32 | LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); | |
| 46 | 33 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, |
| 47 | 34 | StkId val); |
| 48 | 35 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, |
| r242899 | r242900 | |
| 50 | 37 | LUAI_FUNC void luaV_finishOp (lua_State *L); |
| 51 | 38 | LUAI_FUNC void luaV_execute (lua_State *L); |
| 52 | 39 | LUAI_FUNC void luaV_concat (lua_State *L, int total); |
| 53 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); | |
| 54 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); | |
| 55 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); | |
| 40 | LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, | |
| 41 | const TValue *rc, TMS op); | |
| 56 | 42 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); |
| 57 | 43 | |
| 58 | 44 | #endif |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lzio.c,v 1.3 | |
| 2 | ** $Id: lzio.c,v 1.35.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Buffered streams |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | #define lzio_c | |
| 8 | #define LUA_CORE | |
| 9 | 7 | |
| 10 | #include "lprefix.h" | |
| 11 | ||
| 12 | ||
| 13 | 8 | #include <string.h> |
| 14 | 9 | |
| 10 | #define lzio_c | |
| 11 | #define LUA_CORE | |
| 12 | ||
| 15 | 13 | #include "lua.h" |
| 16 | 14 | |
| 17 | 15 | #include "llimits.h" |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /* |
| 2 | ** $Id: lzio.h,v 1. | |
| 2 | ** $Id: lzio.h,v 1.26.1.1 2013/04/12 18:48:47 roberto Exp $ | |
| 3 | 3 | ** Buffered streams |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| r242899 | r242900 | |
| 32 | 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) |
| 33 | 33 | #define luaZ_bufflen(buff) ((buff)->n) |
| 34 | 34 | |
| 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) | |
| 36 | 35 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) |
| 37 | 36 | |
| 38 | 37 | |
| 39 | 38 | #define luaZ_resizebuffer(L, buff, size) \ |
| 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ | |
| 41 | (buff)->buffsize, size), \ | |
| 39 | (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ | |
| 42 | 40 | (buff)->buffsize = size) |
| 43 | 41 | |
| 44 | 42 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) |
| r242899 | r242900 | |
| 47 | 45 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); |
| 48 | 46 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, |
| 49 | 47 | void *data); |
| 50 | LUAI_FUNC size_t luaZ_read (ZIO* z, void | |
| 48 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ | |
| 51 | 49 | |
| 52 | 50 | |
| 53 | 51 | |
| r242899 | r242900 | |
| 57 | 55 | size_t n; /* bytes still unread */ |
| 58 | 56 | const char *p; /* current position in buffer */ |
| 59 | 57 | lua_Reader reader; /* reader function */ |
| 60 | void | |
| 58 | void* data; /* additional data */ | |
| 61 | 59 | lua_State *L; /* Lua state (for reader) */ |
| 62 | 60 | }; |
| 63 | 61 |
| r242899 | r242900 | |
|---|---|---|
| 493 | 493 | DEFS += -DMAME_DEBUG_FAST |
| 494 | 494 | endif |
| 495 | 495 | |
| 496 | # To support casting in Lua 5.3 | |
| 497 | DEFS += -DLUA_COMPAT_APIINTCASTS | |
| 498 | ||
| 499 | 496 | #------------------------------------------------- |
| 500 | 497 | # compile flags |
| 501 | 498 | # CCOMFLAGS are common flags |
| r242899 | r242900 | |
|---|---|---|
| 48 | 48 | save_item(NAME(m_gg_bypass)); |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | void nes_ggenie_device::pcb_start(running_machine &machine, UINT8 *ciram_ptr, bool cart_mounted) | |
| 52 | { | |
| 53 | device_nes_cart_interface::pcb_start(machine, ciram_ptr, cart_mounted); | |
| 54 | if (m_ggslot->m_cart) | |
| 55 | m_ggslot->pcb_start(m_ciram); | |
| 56 | } | |
| 57 | ||
| 58 | 51 | void nes_ggenie_device::pcb_reset() |
| 59 | 52 | { |
| 60 | 53 | m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; |
| r242899 | r242900 | |
| 65 | 58 | m_gg_bypass = 0; |
| 66 | 59 | |
| 67 | 60 | if (m_ggslot->m_cart) |
| 61 | { | |
| 62 | m_ggslot->pcb_start(m_ciram); | |
| 68 | 63 | m_ggslot->m_cart->pcb_reset(); |
| 64 | } | |
| 69 | 65 | } |
| 70 | 66 | |
| 71 | 67 |
| r242899 | r242900 | |
|---|---|---|
| 33 | 33 | virtual machine_config_constructor device_mconfig_additions() const; |
| 34 | 34 | |
| 35 | 35 | virtual void pcb_reset(); |
| 36 | virtual void pcb_start(running_machine &machine, UINT8 *ciram_ptr, bool cart_mounted); | |
| 37 | 36 | |
| 38 | 37 | private: |
| 39 | 38 | // emulate the Game Genie! |
| r242899 | r242900 | |
|---|---|---|
| 216 | 216 | virtual void scanline_irq(int scanline, int vblank, int blanked) {} |
| 217 | 217 | |
| 218 | 218 | virtual void pcb_reset() {} // many pcb expect specific PRG/CHR banking at start |
| 219 | v | |
| 219 | void pcb_start(running_machine &machine, UINT8 *ciram_ptr, bool cart_mounted); | |
| 220 | 220 | void pcb_reg_postload(running_machine &machine); |
| 221 | 221 | void nes_banks_restore(); |
| 222 | 222 |
| r242899 | r242900 | |
|---|---|---|
| 18 | 18 | #include "un7z.h" |
| 19 | 19 | #include "validity.h" |
| 20 | 20 | #include "sound/samples.h" |
| 21 | #include "cliopts.h" | |
| 22 | 21 | #include "clifront.h" |
| 23 | 22 | #include "xmlfile.h" |
| 24 | 23 | |
| 25 | #include "drivenum.h" | |
| 26 | ||
| 27 | 24 | #include <new> |
| 28 | 25 | #include <ctype.h> |
| 29 | 26 | |
| 30 | 27 | |
| 28 | //************************************************************************** | |
| 29 | // COMMAND-LINE OPTIONS | |
| 30 | //************************************************************************** | |
| 31 | 31 | |
| 32 | // media_identifier class identifies media by hash via a search in | |
| 33 | // the driver database | |
| 34 | class media_identifier | |
| 32 | const options_entry cli_options::s_option_entries[] = | |
| 35 | 33 | { |
| 36 | public: | |
| 37 | // construction/destruction | |
| 38 | media_identifier(cli_options &options); | |
| 34 | /* core commands */ | |
| 35 | { NULL, NULL, OPTION_HEADER, "CORE COMMANDS" }, | |
| 36 | { CLICOMMAND_HELP ";h;?", "0", OPTION_COMMAND, "show help message" }, | |
| 37 | { CLICOMMAND_VALIDATE ";valid", "0", OPTION_COMMAND, "perform driver validation on all game drivers" }, | |
| 39 | 38 | |
| 40 | // getters | |
| 41 | int total() const { return m_total; } | |
| 42 | int matches() const { return m_matches; } | |
| 43 | int nonroms() const { return m_nonroms; } | |
| 39 | /* configuration commands */ | |
| 40 | { NULL, NULL, OPTION_HEADER, "CONFIGURATION COMMANDS" }, | |
| 41 | { CLICOMMAND_CREATECONFIG ";cc", "0", OPTION_COMMAND, "create the default configuration file" }, | |
| 42 | { CLICOMMAND_SHOWCONFIG ";sc", "0", OPTION_COMMAND, "display running parameters" }, | |
| 43 | { CLICOMMAND_SHOWUSAGE ";su", "0", OPTION_COMMAND, "show this help" }, | |
| 44 | 44 | |
| 45 | // operations | |
| 46 | void reset() { m_total = m_matches = m_nonroms = 0; } | |
| 47 | void identify(const char *name); | |
| 48 | void identify_file(const char *name); | |
| 49 | void identify_data(const char *name, const UINT8 *data, int length); | |
| 50 | int find_by_hash(const hash_collection &hashes, int length); | |
| 51 | ||
| 52 | private: | |
| 53 | // internal state | |
| 54 | driver_enumerator m_drivlist; | |
| 55 | int m_total; | |
| 56 | int m_matches; | |
| 57 | int m_nonroms; | |
| 45 | /* frontend commands */ | |
| 46 | { NULL, NULL, OPTION_HEADER, "FRONTEND COMMANDS" }, | |
| 47 | { CLICOMMAND_LISTXML ";lx", "0", OPTION_COMMAND, "all available info on driver in XML format" }, | |
| 48 | { CLICOMMAND_LISTFULL ";ll", "0", OPTION_COMMAND, "short name, full name" }, | |
| 49 | { CLICOMMAND_LISTSOURCE ";ls", "0", OPTION_COMMAND, "driver sourcefile" }, | |
| 50 | { CLICOMMAND_LISTCLONES ";lc", "0", OPTION_COMMAND, "show clones" }, | |
| 51 | { CLICOMMAND_LISTBROTHERS ";lb", "0", OPTION_COMMAND, "show \"brothers\", or other drivers from same sourcefile" }, | |
| 52 | { CLICOMMAND_LISTCRC, "0", OPTION_COMMAND, "CRC-32s" }, | |
| 53 | { CLICOMMAND_LISTROMS ";lr", "0", OPTION_COMMAND, "list required roms for a driver" }, | |
| 54 | { CLICOMMAND_LISTSAMPLES, "0", OPTION_COMMAND, "list optional samples for a driver" }, | |
| 55 | { CLICOMMAND_VERIFYROMS, "0", OPTION_COMMAND, "report romsets that have problems" }, | |
| 56 | { CLICOMMAND_VERIFYSAMPLES, "0", OPTION_COMMAND, "report samplesets that have problems" }, | |
| 57 | { CLICOMMAND_ROMIDENT, "0", OPTION_COMMAND, "compare files with known MAME roms" }, | |
| 58 | { CLICOMMAND_LISTDEVICES ";ld", "0", OPTION_COMMAND, "list available devices" }, | |
| 59 | { CLICOMMAND_LISTSLOTS ";lslot", "0", OPTION_COMMAND, "list available slots and slot devices" }, | |
| 60 | { CLICOMMAND_LISTMEDIA ";lm", "0", OPTION_COMMAND, "list available media for the system" }, | |
| 61 | { CLICOMMAND_LISTSOFTWARE ";lsoft", "0", OPTION_COMMAND, "list known software for the system" }, | |
| 62 | { CLICOMMAND_VERIFYSOFTWARE ";vsoft", "0", OPTION_COMMAND, "verify known software for the system" }, | |
| 63 | { CLICOMMAND_GETSOFTLIST ";glist", "0", OPTION_COMMAND, "retrieve software list by name" }, | |
| 64 | { CLICOMMAND_VERIFYSOFTLIST ";vlist", "0", OPTION_COMMAND, "verify software list by name" }, | |
| 65 | { CLICOMMAND_LIST_MIDI_DEVICES ";mlist", "0", OPTION_COMMAND, "list available MIDI I/O devices" }, | |
| 66 | { CLICOMMAND_LIST_NETWORK_ADAPTERS ";nlist", "0", OPTION_COMMAND, "list available network adapters" }, | |
| 67 | { NULL } | |
| 58 | 68 | }; |
| 59 | 69 | |
| 60 | 70 | |
| 71 | ||
| 61 | 72 | //************************************************************************** |
| 73 | // CLI OPTIONS | |
| 74 | //************************************************************************** | |
| 75 | ||
| 76 | //------------------------------------------------- | |
| 77 | // cli_options - constructor | |
| 78 | //------------------------------------------------- | |
| 79 | ||
| 80 | cli_options::cli_options() | |
| 81 | { | |
| 82 | add_entries(s_option_entries); | |
| 83 | } | |
| 84 | ||
| 85 | ||
| 86 | ||
| 87 | //************************************************************************** | |
| 62 | 88 | // CLI FRONTEND |
| 63 | 89 | //************************************************************************** |
| 64 | 90 | |
| r242899 | r242900 | |
| 748 | 774 | } |
| 749 | 775 | |
| 750 | 776 | //------------------------------------------------- |
| 777 | // listmididevices - output the list of MIDI devices | |
| 778 | // available in the current system to be used | |
| 779 | //------------------------------------------------- | |
| 780 | ||
| 781 | void cli_frontend::listmididevices(const char *gamename) | |
| 782 | { | |
| 783 | m_osd.list_midi_devices(); | |
| 784 | } | |
| 785 | ||
| 786 | ||
| 787 | //------------------------------------------------- | |
| 788 | // listnetworkadapters - output the list of network | |
| 789 | // adapters available in the current system to be used | |
| 790 | //------------------------------------------------- | |
| 791 | ||
| 792 | void cli_frontend::listnetworkadapters(const char *gamename) | |
| 793 | { | |
| 794 | m_osd.list_network_adapters(); | |
| 795 | } | |
| 796 | ||
| 797 | ||
| 798 | //------------------------------------------------- | |
| 751 | 799 | // verifyroms - verify the ROM sets of one or |
| 752 | 800 | // more games |
| 753 | 801 | //------------------------------------------------- |
| r242899 | r242900 | |
| 1600 | 1648 | { CLICOMMAND_VERIFYSAMPLES, &cli_frontend::verifysamples }, |
| 1601 | 1649 | { CLICOMMAND_LISTMEDIA, &cli_frontend::listmedia }, |
| 1602 | 1650 | { CLICOMMAND_LISTSOFTWARE, &cli_frontend::listsoftware }, |
| 1603 | { CLICOMMAND_VERIFYSOFTWARE,&cli_frontend::verifysoftware }, | |
| 1651 | { CLICOMMAND_VERIFYSOFTWARE, &cli_frontend::verifysoftware }, | |
| 1604 | 1652 | { CLICOMMAND_ROMIDENT, &cli_frontend::romident }, |
| 1605 | 1653 | { CLICOMMAND_GETSOFTLIST, &cli_frontend::getsoftlist }, |
| 1606 | { CLICOMMAND_VERIFYSOFTLIST,&cli_frontend::verifysoftlist }, | |
| 1654 | { CLICOMMAND_VERIFYSOFTLIST, &cli_frontend::verifysoftlist }, | |
| 1655 | { CLICOMMAND_LIST_MIDI_DEVICES, &cli_frontend::listmididevices }, | |
| 1656 | { CLICOMMAND_LIST_NETWORK_ADAPTERS, &cli_frontend::listnetworkadapters }, | |
| 1607 | 1657 | }; |
| 1608 | 1658 | |
| 1609 | 1659 | // find the command |
| r242899 | r242900 | |
| 1616 | 1666 | return; |
| 1617 | 1667 | } |
| 1618 | 1668 | |
| 1619 | if (!m_osd.execute_command(m_options.command())) | |
| 1620 | // if we get here, we don't know what has been requested | |
| 1621 | throw emu_fatalerror(MAMERR_INVALID_CONFIG, "Unknown command '%s' specified", m_options.command()); | |
| 1669 | // if we get here, we don't know what has been requested | |
| 1670 | throw emu_fatalerror(MAMERR_INVALID_CONFIG, "Unknown command '%s' specified", m_options.command()); | |
| 1622 | 1671 | } |
| 1623 | 1672 | |
| 1624 | 1673 |
| r242899 | r242900 | |
|---|---|---|
| 13 | 13 | #ifndef __CLIFRONT_H__ |
| 14 | 14 | #define __CLIFRONT_H__ |
| 15 | 15 | |
| 16 | #include "emu.h" | |
| 17 | #include "cliopts.h" | |
| 18 | #include "osdepend.h" | |
| 16 | #include "emuopts.h" | |
| 17 | #include "drivenum.h" | |
| 19 | 18 | |
| 20 | 19 | |
| 21 | 20 | //************************************************************************** |
| 21 | // CONSTANTS | |
| 22 | //************************************************************************** | |
| 23 | ||
| 24 | // core commands | |
| 25 | #define CLICOMMAND_HELP "help" | |
| 26 | #define CLICOMMAND_VALIDATE "validate" | |
| 27 | ||
| 28 | // configuration commands | |
| 29 | #define CLICOMMAND_CREATECONFIG "createconfig" | |
| 30 | #define CLICOMMAND_SHOWCONFIG "showconfig" | |
| 31 | #define CLICOMMAND_SHOWUSAGE "showusage" | |
| 32 | ||
| 33 | // frontend commands | |
| 34 | #define CLICOMMAND_LISTXML "listxml" | |
| 35 | #define CLICOMMAND_LISTFULL "listfull" | |
| 36 | #define CLICOMMAND_LISTSOURCE "listsource" | |
| 37 | #define CLICOMMAND_LISTCLONES "listclones" | |
| 38 | #define CLICOMMAND_LISTBROTHERS "listbrothers" | |
| 39 | #define CLICOMMAND_LISTCRC "listcrc" | |
| 40 | #define CLICOMMAND_LISTROMS "listroms" | |
| 41 | #define CLICOMMAND_LISTSAMPLES "listsamples" | |
| 42 | #define CLICOMMAND_VERIFYROMS "verifyroms" | |
| 43 | #define CLICOMMAND_VERIFYSAMPLES "verifysamples" | |
| 44 | #define CLICOMMAND_ROMIDENT "romident" | |
| 45 | #define CLICOMMAND_LISTDEVICES "listdevices" | |
| 46 | #define CLICOMMAND_LISTSLOTS "listslots" | |
| 47 | #define CLICOMMAND_LISTMEDIA "listmedia" // needed by MESS | |
| 48 | #define CLICOMMAND_LISTSOFTWARE "listsoftware" | |
| 49 | #define CLICOMMAND_VERIFYSOFTWARE "verifysoftware" | |
| 50 | #define CLICOMMAND_GETSOFTLIST "getsoftlist" | |
| 51 | #define CLICOMMAND_VERIFYSOFTLIST "verifysoftlist" | |
| 52 | #define CLICOMMAND_LIST_MIDI_DEVICES "listmidi" | |
| 53 | #define CLICOMMAND_LIST_NETWORK_ADAPTERS "listnetwork" | |
| 54 | ||
| 55 | ||
| 56 | //************************************************************************** | |
| 22 | 57 | // TYPE DEFINITIONS |
| 23 | 58 | //************************************************************************** |
| 24 | 59 | |
| 60 | // cli_options wraps the general emu options with CLI-specific additions | |
| 61 | class cli_options : public emu_options | |
| 62 | { | |
| 63 | public: | |
| 64 | // construction/destruction | |
| 65 | cli_options(); | |
| 25 | 66 | |
| 67 | private: | |
| 68 | static const options_entry s_option_entries[]; | |
| 69 | }; | |
| 70 | ||
| 71 | ||
| 26 | 72 | // cli_frontend handles command-line processing and emulator execution |
| 27 | 73 | class cli_frontend |
| 28 | 74 | { |
| r242899 | r242900 | |
| 74 | 120 | }; |
| 75 | 121 | |
| 76 | 122 | |
| 123 | // media_identifier class identifies media by hash via a search in | |
| 124 | // the driver database | |
| 125 | class media_identifier | |
| 126 | { | |
| 127 | public: | |
| 128 | // construction/destruction | |
| 129 | media_identifier(cli_options &options); | |
| 77 | 130 | |
| 131 | // getters | |
| 132 | int total() const { return m_total; } | |
| 133 | int matches() const { return m_matches; } | |
| 134 | int nonroms() const { return m_nonroms; } | |
| 78 | 135 | |
| 136 | // operations | |
| 137 | void reset() { m_total = m_matches = m_nonroms = 0; } | |
| 138 | void identify(const char *name); | |
| 139 | void identify_file(const char *name); | |
| 140 | void identify_data(const char *name, const UINT8 *data, int length); | |
| 141 | int find_by_hash(const hash_collection &hashes, int length); | |
| 142 | ||
| 143 | private: | |
| 144 | // internal state | |
| 145 | driver_enumerator m_drivlist; | |
| 146 | int m_total; | |
| 147 | int m_matches; | |
| 148 | int m_nonroms; | |
| 149 | }; | |
| 150 | ||
| 151 | ||
| 152 | ||
| 79 | 153 | #endif /* __CLIFRONT_H__ */ |
| r242899 | r242900 | |
|---|---|---|
| 1 | // license:BSD-3-Clause | |
| 2 | // copyright-holders:Aaron Giles | |
| 3 | /*************************************************************************** | |
| 4 | ||
| 5 | cliopts.c | |
| 6 | ||
| 7 | ***************************************************************************/ | |
| 8 | ||
| 9 | #include "cliopts.h" | |
| 10 | #include "clifront.h" | |
| 11 | ||
| 12 | //************************************************************************** | |
| 13 | // COMMAND-LINE OPTIONS | |
| 14 | //************************************************************************** | |
| 15 | ||
| 16 | const options_entry cli_options::s_option_entries[] = | |
| 17 | { | |
| 18 | /* core commands */ | |
| 19 | { NULL, NULL, OPTION_HEADER, "CORE COMMANDS" }, | |
| 20 | { CLICOMMAND_HELP ";h;?", "0", OPTION_COMMAND, "show help message" }, | |
| 21 | { CLICOMMAND_VALIDATE ";valid", "0", OPTION_COMMAND, "perform driver validation on all game drivers" }, | |
| 22 | ||
| 23 | /* configuration commands */ | |
| 24 | { NULL, NULL, OPTION_HEADER, "CONFIGURATION COMMANDS" }, | |
| 25 | { CLICOMMAND_CREATECONFIG ";cc", "0", OPTION_COMMAND, "create the default configuration file" }, | |
| 26 | { CLICOMMAND_SHOWCONFIG ";sc", "0", OPTION_COMMAND, "display running parameters" }, | |
| 27 | { CLICOMMAND_SHOWUSAGE ";su", "0", OPTION_COMMAND, "show this help" }, | |
| 28 | ||
| 29 | /* frontend commands */ | |
| 30 | { NULL, NULL, OPTION_HEADER, "FRONTEND COMMANDS" }, | |
| 31 | { CLICOMMAND_LISTXML ";lx", "0", OPTION_COMMAND, "all available info on driver in XML format" }, | |
| 32 | { CLICOMMAND_LISTFULL ";ll", "0", OPTION_COMMAND, "short name, full name" }, | |
| 33 | { CLICOMMAND_LISTSOURCE ";ls", "0", OPTION_COMMAND, "driver sourcefile" }, | |
| 34 | { CLICOMMAND_LISTCLONES ";lc", "0", OPTION_COMMAND, "show clones" }, | |
| 35 | { CLICOMMAND_LISTBROTHERS ";lb", "0", OPTION_COMMAND, "show \"brothers\", or other drivers from same sourcefile" }, | |
| 36 | { CLICOMMAND_LISTCRC, "0", OPTION_COMMAND, "CRC-32s" }, | |
| 37 | { CLICOMMAND_LISTROMS ";lr", "0", OPTION_COMMAND, "list required roms for a driver" }, | |
| 38 | { CLICOMMAND_LISTSAMPLES, "0", OPTION_COMMAND, "list optional samples for a driver" }, | |
| 39 | { CLICOMMAND_VERIFYROMS, "0", OPTION_COMMAND, "report romsets that have problems" }, | |
| 40 | { CLICOMMAND_VERIFYSAMPLES, "0", OPTION_COMMAND, "report samplesets that have problems" }, | |
| 41 | { CLICOMMAND_ROMIDENT, "0", OPTION_COMMAND, "compare files with known MAME roms" }, | |
| 42 | { CLICOMMAND_LISTDEVICES ";ld", "0", OPTION_COMMAND, "list available devices" }, | |
| 43 | { CLICOMMAND_LISTSLOTS ";lslot", "0", OPTION_COMMAND, "list available slots and slot devices" }, | |
| 44 | { CLICOMMAND_LISTMEDIA ";lm", "0", OPTION_COMMAND, "list available media for the system" }, | |
| 45 | { CLICOMMAND_LISTSOFTWARE ";lsoft", "0", OPTION_COMMAND, "list known software for the system" }, | |
| 46 | { CLICOMMAND_VERIFYSOFTWARE ";vsoft", "0", OPTION_COMMAND, "verify known software for the system" }, | |
| 47 | { CLICOMMAND_GETSOFTLIST ";glist", "0", OPTION_COMMAND, "retrieve software list by name" }, | |
| 48 | { CLICOMMAND_VERIFYSOFTLIST ";vlist", "0", OPTION_COMMAND, "verify software list by name" }, | |
| 49 | { NULL } | |
| 50 | }; | |
| 51 | ||
| 52 | //************************************************************************** | |
| 53 | // CLI OPTIONS | |
| 54 | //************************************************************************** | |
| 55 | ||
| 56 | //------------------------------------------------- | |
| 57 | // cli_options - constructor | |
| 58 | //------------------------------------------------- | |
| 59 | ||
| 60 | cli_options::cli_options() | |
| 61 | : emu_options() | |
| 62 | { | |
| 63 | add_entries(cli_options::s_option_entries); | |
| 64 | } | |
| 65 |
| r242899 | r242900 | |
|---|---|---|
| 1 | // license:BSD-3-Clause | |
| 2 | // copyright-holders:Aaron Giles | |
| 3 | /*************************************************************************** | |
| 4 | ||
| 5 | clifront.h | |
| 6 | ||
| 7 | Command-line interface frontend for MAME. | |
| 8 | ||
| 9 | ***************************************************************************/ | |
| 10 | ||
| 11 | #pragma once | |
| 12 | ||
| 13 | #ifndef __CLIOPTS_H__ | |
| 14 | #define __CLIOPTS_H__ | |
| 15 | ||
| 16 | #include "emuopts.h" | |
| 17 | ||
| 18 | //************************************************************************** | |
| 19 | // CONSTANTS | |
| 20 | //************************************************************************** | |
| 21 | ||
| 22 | // core commands | |
| 23 | #define CLICOMMAND_HELP "help" | |
| 24 | #define CLICOMMAND_VALIDATE "validate" | |
| 25 | ||
| 26 | // configuration commands | |
| 27 | #define CLICOMMAND_CREATECONFIG "createconfig" | |
| 28 | #define CLICOMMAND_SHOWCONFIG "showconfig" | |
| 29 | #define CLICOMMAND_SHOWUSAGE "showusage" | |
| 30 | ||
| 31 | // frontend commands | |
| 32 | #define CLICOMMAND_LISTXML "listxml" | |
| 33 | #define CLICOMMAND_LISTFULL "listfull" | |
| 34 | #define CLICOMMAND_LISTSOURCE "listsource" | |
| 35 | #define CLICOMMAND_LISTCLONES "listclones" | |
| 36 | #define CLICOMMAND_LISTBROTHERS "listbrothers" | |
| 37 | #define CLICOMMAND_LISTCRC "listcrc" | |
| 38 | #define CLICOMMAND_LISTROMS "listroms" | |
| 39 | #define CLICOMMAND_LISTSAMPLES "listsamples" | |
| 40 | #define CLICOMMAND_VERIFYROMS "verifyroms" | |
| 41 | #define CLICOMMAND_VERIFYSAMPLES "verifysamples" | |
| 42 | #define CLICOMMAND_ROMIDENT "romident" | |
| 43 | #define CLICOMMAND_LISTDEVICES "listdevices" | |
| 44 | #define CLICOMMAND_LISTSLOTS "listslots" | |
| 45 | #define CLICOMMAND_LISTMEDIA "listmedia" // needed by MESS | |
| 46 | #define CLICOMMAND_LISTSOFTWARE "listsoftware" | |
| 47 | #define CLICOMMAND_VERIFYSOFTWARE "verifysoftware" | |
| 48 | #define CLICOMMAND_GETSOFTLIST "getsoftlist" | |
| 49 | #define CLICOMMAND_VERIFYSOFTLIST "verifysoftlist" | |
| 50 | ||
| 51 | ||
| 52 | //************************************************************************** | |
| 53 | // TYPE DEFINITIONS | |
| 54 | //************************************************************************** | |
| 55 | ||
| 56 | // cli_options wraps the general emu options with CLI-specific additions | |
| 57 | class cli_options : public emu_options | |
| 58 | { | |
| 59 | public: | |
| 60 | // construction/destruction | |
| 61 | cli_options(); | |
| 62 | ||
| 63 | private: | |
| 64 | static const options_entry s_option_entries[]; | |
| 65 | }; | |
| 66 | ||
| 67 | #endif /* __CLIFRONT_H__ */ |
| r242899 | r242900 | |
|---|---|---|
| 110 | 110 | osd_printf_verbose("Optional %s '%s' not found\n", objname, m_tag); |
| 111 | 111 | return !required; |
| 112 | 112 | } |
| 113 | ||
| 114 | ||
| 115 | void finder_base::printf_warning(const char *format, ...) | |
| 116 | { | |
| 117 | va_list argptr; | |
| 118 | char buffer[1024]; | |
| 119 | ||
| 120 | /* do the output */ | |
| 121 | va_start(argptr, format); | |
| 122 | vsnprintf(buffer, 1024, format, argptr); | |
| 123 | osd_printf_warning("%s", buffer); | |
| 124 | va_end(argptr); | |
| 125 | } |
| r242899 | r242900 | |
|---|---|---|
| 57 | 57 | void *find_memshare(UINT8 width, size_t &bytes, bool required); |
| 58 | 58 | bool report_missing(bool found, const char *objname, bool required); |
| 59 | 59 | |
| 60 | void printf_warning(const char *format, ...) ATTR_PRINTF(2,3); | |
| 61 | ||
| 62 | 60 | // internal state |
| 63 | 61 | finder_base *m_next; |
| 64 | 62 | device_t &m_base; |
| r242899 | r242900 | |
| 115 | 113 | this->m_target = dynamic_cast<_DeviceClass *>(device); |
| 116 | 114 | if (device != NULL && this->m_target == NULL) |
| 117 | 115 | { |
| 118 | this->printf_warning("Device '%s' found but is of incorrect type (actual type is %s)\n", this->m_tag, device->name()); | |
| 116 | void osd_printf_warning(const char *format, ...) ATTR_PRINTF(1,2); | |
| 117 | osd_printf_warning("Device '%s' found but is of incorrect type (actual type is %s)\n", this->m_tag, device->name()); | |
| 119 | 118 | } |
| 120 | 119 | return this->report_missing(this->m_target != NULL, "device", _Required); |
| 121 | 120 | } |
| r242899 | r242900 | |
|---|---|---|
| 55 | 55 | $(EMUOBJ)/audit.o \ |
| 56 | 56 | $(EMUOBJ)/cheat.o \ |
| 57 | 57 | $(EMUOBJ)/clifront.o \ |
| 58 | $(EMUOBJ)/cliopts.o \ | |
| 59 | 58 | $(EMUOBJ)/config.o \ |
| 60 | 59 | $(EMUOBJ)/crsshair.o \ |
| 61 | 60 | $(EMUOBJ)/debugger.o \ |
| r242899 | r242900 | |
| 116 | 115 | $(EMUOBJ)/timer.o \ |
| 117 | 116 | $(EMUOBJ)/uiinput.o \ |
| 118 | 117 | $(EMUOBJ)/ui/ui.o \ |
| 118 | $(EMUOBJ)/ui/swlist.o \ | |
| 119 | 119 | $(EMUOBJ)/ui/menu.o \ |
| 120 | 120 | $(EMUOBJ)/ui/mainmenu.o \ |
| 121 | 121 | $(EMUOBJ)/ui/miscmenu.o \ |
| 122 | $(EMUOBJ)/ui/ | |
| 122 | $(EMUOBJ)/ui/selgame.o \ | |
| 123 | 123 | $(EMUOBJ)/ui/filemngr.o \ |
| 124 | 124 | $(EMUOBJ)/ui/filesel.o \ |
| 125 | 125 | $(EMUOBJ)/ui/imgcntrl.o \ |
| 126 | 126 | $(EMUOBJ)/ui/imginfo.o \ |
| 127 | $(EMUOBJ)/ui/inputmap.o \ | |
| 128 | $(EMUOBJ)/ui/selgame.o \ | |
| 129 | $(EMUOBJ)/ui/slotopt.o \ | |
| 130 | $(EMUOBJ)/ui/swlist.o \ | |
| 127 | $(EMUOBJ)/ui/barcode.o \ | |
| 131 | 128 | $(EMUOBJ)/ui/tapectrl.o \ |
| 132 | 129 | $(EMUOBJ)/ui/viewgfx.o \ |
| 133 | 130 | $(EMUOBJ)/validity.o \ |
| r242899 | r242900 | |
| 148 | 145 | $(EMUOBJ)/profiler.o \ |
| 149 | 146 | $(EMUOBJ)/webengine.o \ |
| 150 | 147 | $(OSDOBJ)/osdcore.o \ |
| 148 | $(OSDOBJ)/osdepend.o \ | |
| 151 | 149 | $(OSDOBJ)/osdnet.o \ |
| 152 | 150 | $(OSDOBJ)/modules/sound/none.o \ |
| 153 | 151 | $(OSDOBJ)/modules/debugger/none.o \ |
| r242899 | r242900 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | |
| 3 | | |
| 3 | mamecore.c | |
| 4 | 4 | |
| 5 | 5 | Simple core functions that are defined in emucore.h and which may |
| 6 | 6 | need to be accessed by other MAME-related tools. |
| r242899 | r242900 | |
| 11 | 11 | ****************************************************************************/ |
| 12 | 12 | |
| 13 | 13 | #include "emu.h" |
| 14 | #include "emucore.h" | |
| 15 | #include "osdcore.h" | |
| 16 | 14 | |
| 17 | emu_fatalerror::emu_fatalerror(const char *format, ...) | |
| 18 | : code(0) | |
| 19 | { | |
| 20 | if (format == NULL) | |
| 21 | { | |
| 22 | text[0] = '\0'; | |
| 23 | } | |
| 24 | else | |
| 25 | { | |
| 26 | va_list ap; | |
| 27 | va_start(ap, format); | |
| 28 | vsprintf(text, format, ap); | |
| 29 | va_end(ap); | |
| 30 | } | |
| 31 | osd_break_into_debugger(text); | |
| 32 | } | |
| 33 | ||
| 34 | emu_fatalerror::emu_fatalerror(const char *format, va_list ap) | |
| 35 | : code(0) | |
| 36 | { | |
| 37 | if (format == NULL) | |
| 38 | { | |
| 39 | text[0] = '\0'; | |
| 40 | } | |
| 41 | else | |
| 42 | { | |
| 43 | vsprintf(text, format, ap); | |
| 44 | } | |
| 45 | osd_break_into_debugger(text); | |
| 46 | } | |
| 47 | ||
| 48 | emu_fatalerror::emu_fatalerror(int _exitcode, const char *format, ...) | |
| 49 | : code(_exitcode) | |
| 50 | { | |
| 51 | if (format == NULL) | |
| 52 | { | |
| 53 | text[0] = '\0'; | |
| 54 | } | |
| 55 | else | |
| 56 | { | |
| 57 | va_list ap; | |
| 58 | va_start(ap, format); | |
| 59 | vsprintf(text, format, ap); | |
| 60 | va_end(ap); | |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | emu_fatalerror::emu_fatalerror(int _exitcode, const char *format, va_list ap) | |
| 65 | : code(_exitcode) | |
| 66 | { | |
| 67 | if (format == NULL) | |
| 68 | { | |
| 69 | text[0] = '\0'; | |
| 70 | } | |
| 71 | else | |
| 72 | { | |
| 73 | vsprintf(text, format, ap); | |
| 74 | } | |
| 75 | } | |
| 76 | ||
| 77 | ||
| 78 | 15 | void report_bad_cast(const std::type_info &src_type, const std::type_info &dst_type) |
| 79 | 16 | { |
| 80 | 17 | throw emu_fatalerror("Error: bad downcast<> or device<>. Tried to convert a %s to a %s, which are incompatible.\n", |
| r242899 | r242900 | |
| 86 | 23 | throw emu_fatalerror("Error: bad downcast<> or device<>. Tried to convert the device %s (%s) of type %s to a %s, which are incompatible.\n", |
| 87 | 24 | dev->tag(), dev->name(), src_type.name(), dst_type.name()); |
| 88 | 25 | } |
| 89 | ||
| 90 | void fatalerror(const char *format, ...) | |
| 91 | { | |
| 92 | va_list ap; | |
| 93 | va_start(ap, format); | |
| 94 | emu_fatalerror error(format, ap); | |
| 95 | va_end(ap); | |
| 96 | throw error; | |
| 97 | } | |
| 98 | ||
| 99 | void fatalerror_exitcode(running_machine &machine, int exitcode, const char *format, ...) | |
| 100 | { | |
| 101 | va_list ap; | |
| 102 | va_start(ap, format); | |
| 103 | emu_fatalerror error(exitcode, format, ap); | |
| 104 | va_end(ap); | |
| 105 | throw error; | |
| 106 | } |
| r242899 | r242900 | |
|---|---|---|
| 289 | 289 | class emu_fatalerror : public emu_exception |
| 290 | 290 | { |
| 291 | 291 | public: |
| 292 | emu_fatalerror(const char *format, ...) ATTR_PRINTF(2,3); | |
| 293 | emu_fatalerror(const char *format, va_list ap); | |
| 294 | emu_fatalerror(int _exitcode, const char *format, ...) ATTR_PRINTF(3,4); | |
| 295 | emu_fatalerror(int _exitcode, const char *format, va_list ap); | |
| 292 | emu_fatalerror(const char *format, ...) ATTR_PRINTF(2,3) | |
| 293 | : code(0) | |
| 294 | { | |
| 295 | if (format == NULL) | |
| 296 | { | |
| 297 | text[0] = '\0'; | |
| 298 | } | |
| 299 | else | |
| 300 | { | |
| 301 | va_list ap; | |
| 302 | va_start(ap, format); | |
| 303 | vsprintf(text, format, ap); | |
| 304 | va_end(ap); | |
| 305 | } | |
| 306 | osd_break_into_debugger(text); | |
| 307 | } | |
| 296 | 308 | |
| 309 | emu_fatalerror(const char *format, va_list ap) | |
| 310 | : code(0) | |
| 311 | { | |
| 312 | if (format == NULL) | |
| 313 | { | |
| 314 | text[0] = '\0'; | |
| 315 | } | |
| 316 | else | |
| 317 | { | |
| 318 | vsprintf(text, format, ap); | |
| 319 | } | |
| 320 | osd_break_into_debugger(text); | |
| 321 | } | |
| 322 | ||
| 323 | emu_fatalerror(int _exitcode, const char *format, ...) ATTR_PRINTF(3,4) | |
| 324 | : code(_exitcode) | |
| 325 | { | |
| 326 | if (format == NULL) | |
| 327 | { | |
| 328 | text[0] = '\0'; | |
| 329 | } | |
| 330 | else | |
| 331 | { | |
| 332 | va_list ap; | |
| 333 | va_start(ap, format); | |
| 334 | vsprintf(text, format, ap); | |
| 335 | va_end(ap); | |
| 336 | } | |
| 337 | } | |
| 338 | ||
| 339 | emu_fatalerror(int _exitcode, const char *format, va_list ap) | |
| 340 | : code(_exitcode) | |
| 341 | { | |
| 342 | if (format == NULL) | |
| 343 | { | |
| 344 | text[0] = '\0'; | |
| 345 | } | |
| 346 | else | |
| 347 | { | |
| 348 | vsprintf(text, format, ap); | |
| 349 | } | |
| 350 | } | |
| 351 | ||
| 297 | 352 | const char *string() const { return text; } |
| 298 | 353 | int exitcode() const { return code; } |
| 299 | 354 | |
| r242899 | r242900 | |
| 366 | 421 | ATTR_NORETURN void fatalerror(const char *format, ...) ATTR_PRINTF(1,2); |
| 367 | 422 | ATTR_NORETURN void fatalerror_exitcode(running_machine &machine, int exitcode, const char *format, ...) ATTR_PRINTF(3,4); |
| 368 | 423 | |
| 424 | inline void fatalerror(const char *format, ...) | |
| 425 | { | |
| 426 | va_list ap; | |
| 427 | va_start(ap, format); | |
| 428 | emu_fatalerror error(format, ap); | |
| 429 | va_end(ap); | |
| 430 | throw error; | |
| 431 | } | |
| 432 | ||
| 433 | inline void fatalerror_exitcode(running_machine &machine, int exitcode, const char *format, ...) | |
| 434 | { | |
| 435 | va_list ap; | |
| 436 | va_start(ap, format); | |
| 437 | emu_fatalerror error(exitcode, format, ap); | |
| 438 | va_end(ap); | |
| 439 | throw error; | |
| 440 | } | |
| 441 | ||
| 442 | ||
| 443 | ||
| 369 | 444 | //************************************************************************** |
| 370 | 445 | // INLINE FUNCTIONS |
| 371 | 446 | //************************************************************************** |
| r242899 | r242900 | |
|---|---|---|
| 150 | 150 | |
| 151 | 151 | // debugging options |
| 152 | 152 | { NULL, NULL, OPTION_HEADER, "CORE DEBUGGING OPTIONS" }, |
| 153 | { OPTION_VERBOSE ";v", "0", OPTION_BOOLEAN, "display additional diagnostic information" }, | |
| 154 | { OPTION_LOG, "0", OPTION_BOOLEAN, "generate an error.log file" }, | |
| 155 | { OPTION_OSLOG, "0", OPTION_BOOLEAN, "output error.log data to the system debugger" }, | |
| 156 | { OPTION_DEBUG ";d", "0", OPTION_BOOLEAN, "enable/disable debugger" }, | |
| 157 | 153 | { OPTION_UPDATEINPAUSE, "0", OPTION_BOOLEAN, "keep calling video updates while in pause" }, |
| 158 | 154 | { OPTION_DEBUGSCRIPT, NULL, OPTION_STRING, "script for debugger" }, |
| 159 | 155 | |
| r242899 | r242900 | |
| 191 | 187 | //------------------------------------------------- |
| 192 | 188 | |
| 193 | 189 | emu_options::emu_options() |
| 194 | : core_options() | |
| 195 | 190 | { |
| 196 | add_entries(emu_options::s_option_entries); | |
| 191 | add_entries(s_option_entries); | |
| 192 | add_osd_options(); | |
| 197 | 193 | } |
| 198 | 194 | |
| 199 | 195 | |
| r242899 | r242900 | |
| 508 | 504 | } |
| 509 | 505 | } |
| 510 | 506 | |
| 507 | ||
| 511 | 508 | //------------------------------------------------- |
| 509 | // device_option - return the value of the | |
| 510 | // device-specific option | |
| 511 | //------------------------------------------------- | |
| 512 | ||
| 513 | const char *emu_options::device_option(device_image_interface &image) | |
| 514 | { | |
| 515 | return value(image.instance_name()); | |
| 516 | } | |
| 517 | ||
| 518 | ||
| 519 | //------------------------------------------------- | |
| 512 | 520 | // parse_one_ini - parse a single INI file |
| 513 | 521 | //------------------------------------------------- |
| 514 | 522 |
| r242899 | r242900 | |
|---|---|---|
| 15 | 15 | |
| 16 | 16 | #include "options.h" |
| 17 | 17 | |
| 18 | ||
| 18 | 19 | //************************************************************************** |
| 19 | 20 | // CONSTANTS |
| 20 | 21 | //************************************************************************** |
| r242899 | r242900 | |
| 153 | 154 | #define OPTION_MOUSE_DEVICE "mouse_device" |
| 154 | 155 | |
| 155 | 156 | // core debugging options |
| 156 | #define OPTION_LOG "log" | |
| 157 | #define OPTION_DEBUG "debug" | |
| 158 | #define OPTION_VERBOSE "verbose" | |
| 159 | #define OPTION_OSLOG "oslog" | |
| 160 | 157 | #define OPTION_UPDATEINPAUSE "update_in_pause" |
| 161 | 158 | #define OPTION_DEBUGSCRIPT "debugscript" |
| 162 | 159 | |
| r242899 | r242900 | |
| 191 | 188 | struct game_driver; |
| 192 | 189 | |
| 193 | 190 | |
| 194 | class emu_options : public | |
| 191 | class emu_options : public osd_options | |
| 195 | 192 | { |
| 196 | 193 | static const UINT32 OPTION_FLAG_DEVICE = 0x80000000; |
| 197 | 194 | |
| r242899 | r242900 | |
| 318 | 315 | bool joystick_contradictory() const { return bool_value(OPTION_JOYSTICK_CONTRADICTORY); } |
| 319 | 316 | int coin_impulse() const { return int_value(OPTION_COIN_IMPULSE); } |
| 320 | 317 | |
| 321 | // core debugging options | |
| 322 | bool log() const { return bool_value(OPTION_LOG); } | |
| 323 | bool debug() const { return bool_value(OPTION_DEBUG); } | |
| 324 | bool verbose() const { return bool_value(OPTION_VERBOSE); } | |
| 325 | bool oslog() const { return bool_value(OPTION_OSLOG); } | |
| 318 | // core debugging options | |
| 326 | 319 | const char *debug_script() const { return value(OPTION_DEBUGSCRIPT); } |
| 327 | 320 | bool update_in_pause() const { return bool_value(OPTION_UPDATEINPAUSE); } |
| 328 | 321 | |
| r242899 | r242900 | |
| 349 | 342 | const char *http_path() const { return value(OPTION_HTTP_PATH); } |
| 350 | 343 | bool console() const { return bool_value(OPTION_CONSOLE); } |
| 351 | 344 | |
| 352 | // FIXME: Couriersud: This should be in image_device_exit | |
| 345 | // device-specific options | |
| 346 | const char *device_option(device_image_interface &image); | |
| 347 | ||
| 353 | 348 | void remove_device_options(); |
| 354 | 349 | |
| 355 | 350 | const char *main_value(astring &buffer, const char *option) const; |
| r242899 | r242900 | |
|---|---|---|
| 210 | 210 | for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) |
| 211 | 211 | { |
| 212 | 212 | /* is an image specified for this image */ |
| 213 | image_name = machine.options().v | |
| 213 | image_name = machine.options().device_option(*image); | |
| 214 | 214 | |
| 215 | 215 | if ((image_name != NULL) && (image_name[0] != '\0')) |
| 216 | 216 | { |
| r242899 | r242900 | |
|---|---|---|
| 162 | 162 | fif_list(NULL) |
| 163 | 163 | { |
| 164 | 164 | extension_list[0] = '\0'; |
| 165 | m_err = IMAGE_ERROR_INVALIDIMAGE; | |
| 166 | 165 | } |
| 167 | 166 | |
| 168 | 167 | //------------------------------------------------- |
| r242899 | r242900 | |
|---|---|---|
| 68 | 68 | { |
| 69 | 69 | const char *msg = lua_tostring(m_lua_state, -1); |
| 70 | 70 | if (msg == NULL) msg = "(error object is not a string)"; |
| 71 | lua_writestringerror("%s\n", msg); | |
| 71 | luai_writestringerror("%s\n", msg); | |
| 72 | 72 | lua_pop(m_lua_state, 1); |
| 73 | 73 | /* force a complete garbage collection in case of errors */ |
| 74 | 74 | lua_gc(m_lua_state, LUA_GCCOLLECT, 0); |
| r242899 | r242900 | |
| 360 | 360 | } else if (strcmp(hookname, "frame") == 0) { |
| 361 | 361 | hook_frame_cb.set(L, 1); |
| 362 | 362 | } else { |
| 363 | lua_writestringerror("%s", "Unknown hook name, aborting.\n"); | |
| 363 | luai_writestringerror("%s", "Unknown hook name, aborting.\n"); | |
| 364 | 364 | } |
| 365 | 365 | } |
| 366 | 366 | |
| r242899 | r242900 | |
| 948 | 948 | lua_getglobal(m_lua_state, "print"); |
| 949 | 949 | lua_insert(m_lua_state, 1); |
| 950 | 950 | if (lua_pcall(m_lua_state, lua_gettop(m_lua_state) - 1, 0, 0) != LUA_OK) |
| 951 | lua_writestringerror("%s\n", lua_pushfstring(m_lua_state, | |
| 951 | luai_writestringerror("%s\n", lua_pushfstring(m_lua_state, | |
| 952 | 952 | "error calling " LUA_QL("print") " (%s)", |
| 953 | 953 | lua_tostring(m_lua_state, -1))); |
| 954 | 954 | } |
| r242899 | r242900 | |
|---|---|---|
| 244 | 244 | |
| 245 | 245 | m_cpu->i8051_set_serial_rx_callback(read8_delegate(FUNC(qs1000_device::data_to_i8052),this)); |
| 246 | 246 | |
| 247 | save_item(NAME(m_serial_data_in)); | |
| 248 | save_item(NAME(m_wave_regs)); | |
| 249 | ||
| 250 | for (int i = 0; i < QS1000_CHANNELS; i++) | |
| 251 | { | |
| 252 | save_item(NAME(m_channels[i].m_acc), i); | |
| 253 | save_item(NAME(m_channels[i].m_adpcm_signal), i); | |
| 254 | save_item(NAME(m_channels[i].m_start), i); | |
| 255 | save_item(NAME(m_channels[i].m_addr), i); | |
| 256 | save_item(NAME(m_channels[i].m_adpcm_addr), i); | |
| 257 | save_item(NAME(m_channels[i].m_loop_start), i); | |
| 258 | save_item(NAME(m_channels[i].m_loop_end), i); | |
| 259 | save_item(NAME(m_channels[i].m_freq), i); | |
| 260 | save_item(NAME(m_channels[i].m_flags), i); | |
| 261 | save_item(NAME(m_channels[i].m_regs), i); | |
| 262 | save_item(NAME(m_channels[i].m_adpcm.m_signal), i); | |
| 263 | save_item(NAME(m_channels[i].m_adpcm.m_step), i); | |
| 264 | } | |
| 247 | // TODO: register state for saving | |
| 265 | 248 | } |
| 266 | 249 | |
| 267 | 250 |
| r242899 | r242900 | |
|---|---|---|
| 66 | 66 | void ui_menu_file_manager::populate() |
| 67 | 67 | { |
| 68 | 68 | astring buffer; |
| 69 | | |
| 69 | astring tmp_name; | |
| 70 | 70 | |
| 71 | 71 | // cycle through all devices for this system |
| 72 | 72 | image_interface_iterator iter(machine().root_device()); |
| 73 | 73 | for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) |
| 74 | 74 | { |
| 75 | if (first) | |
| 76 | first = false; | |
| 77 | else | |
| 78 | item_append("", NULL, MENU_FLAG_DISABLE, NULL); | |
| 79 | ||
| 80 | 75 | // get the image type/id |
| 81 | buffer.printf("%s (%s)", image->instance_name(), image->brief_instance_name()); | |
| 82 | item_append(buffer, "", MENU_FLAG_DISABLE, NULL); | |
| 83 | item_append("Device", image->device().tag(), MENU_FLAG_DISABLE, NULL); | |
| 76 | buffer.printf( | |
| 77 | "%s (%s)", | |
| 78 | image->device().name(), image->brief_instance_name()); | |
| 84 | 79 | |
| 85 | 80 | // get the base name |
| 86 | 81 | if (image->basename() != NULL) |
| 87 | 82 | { |
| 88 | | |
| 83 | tmp_name.cpy(image->basename()); | |
| 89 | 84 | |
| 90 | 85 | // if the image has been loaded through softlist, also show the loaded part |
| 91 | 86 | if (image->part_entry() != NULL) |
| r242899 | r242900 | |
| 93 | 88 | const software_part *tmp = image->part_entry(); |
| 94 | 89 | if (tmp->name() != NULL) |
| 95 | 90 | { |
| 96 | buffer.cat(" ("); | |
| 97 | buffer.cat(tmp->name()); | |
| 91 | tmp_name.cat(" ("); | |
| 92 | tmp_name.cat(tmp->name()); | |
| 98 | 93 | // also check if this part has a specific part_id (e.g. "Map Disc", "Bonus Disc", etc.), and in case display it |
| 99 | 94 | if (image->get_feature("part_id") != NULL) |
| 100 | 95 | { |
| 101 | buffer.cat(": "); | |
| 102 | buffer.cat(image->get_feature("part_id")); | |
| 96 | tmp_name.cat(": "); | |
| 97 | tmp_name.cat(image->get_feature("part_id")); | |
| 103 | 98 | } |
| 104 | | |
| 99 | tmp_name.cat(")"); | |
| 105 | 100 | } |
| 106 | 101 | } |
| 107 | 102 | } |
| 108 | 103 | else |
| 109 | | |
| 104 | tmp_name.cpy("---"); | |
| 110 | 105 | |
| 111 | 106 | // record the menu item |
| 112 | item_append( | |
| 107 | item_append(buffer, tmp_name.cstr(), 0, (void *) image); | |
| 113 | 108 | } |
| 114 | 109 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); |
| 115 | 110 | item_append("Reset", NULL, 0, (void *)1); |
| r242899 | r242900 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | ui/inputmap.c | |
| 4 | ||
| 5 | Internal menus for input mappings. | |
| 6 | ||
| 7 | Copyright Nicola Salmoria and the MAME Team. | |
| 8 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 9 | ||
| 10 | *********************************************************************/ | |
| 11 | ||
| 12 | #include "emu.h" | |
| 13 | ||
| 14 | #include "uiinput.h" | |
| 15 | #include "ui/ui.h" | |
| 16 | #include "ui/inputmap.h" | |
| 17 | ||
| 18 | ||
| 19 | /*************************************************************************** | |
| 20 | CONSTANTS | |
| 21 | ***************************************************************************/ | |
| 22 | ||
| 23 | #define MAX_PHYSICAL_DIPS 10 | |
| 24 | #define MAX_INPUT_PORTS 32 | |
| 25 | #define MAX_BITS_PER_PORT 32 | |
| 26 | ||
| 27 | /* DIP switch rendering parameters */ | |
| 28 | #define DIP_SWITCH_HEIGHT 0.05f | |
| 29 | #define DIP_SWITCH_SPACING 0.01 | |
| 30 | #define SINGLE_TOGGLE_SWITCH_FIELD_WIDTH 0.025f | |
| 31 | #define SINGLE_TOGGLE_SWITCH_WIDTH 0.020f | |
| 32 | /* make the switch 80% of the width space and 1/2 of the switch height */ | |
| 33 | #define PERCENTAGE_OF_HALF_FIELD_USED 0.80f | |
| 34 | #define SINGLE_TOGGLE_SWITCH_HEIGHT ((DIP_SWITCH_HEIGHT / 2) * PERCENTAGE_OF_HALF_FIELD_USED) | |
| 35 | ||
| 36 | ||
| 37 | ||
| 38 | /*------------------------------------------------- | |
| 39 | menu_input_groups_populate - populate the | |
| 40 | input groups menu | |
| 41 | -------------------------------------------------*/ | |
| 42 | ||
| 43 | ui_menu_input_groups::ui_menu_input_groups(running_machine &machine, render_container *container) : ui_menu(machine, container) | |
| 44 | { | |
| 45 | } | |
| 46 | ||
| 47 | void ui_menu_input_groups::populate() | |
| 48 | { | |
| 49 | int player; | |
| 50 | ||
| 51 | /* build up the menu */ | |
| 52 | item_append("User Interface", NULL, 0, (void *)(IPG_UI + 1)); | |
| 53 | for (player = 0; player < MAX_PLAYERS; player++) | |
| 54 | { | |
| 55 | char buffer[40]; | |
| 56 | sprintf(buffer, "Player %d Controls", player + 1); | |
| 57 | item_append(buffer, NULL, 0, (void *)(FPTR)(IPG_PLAYER1 + player + 1)); | |
| 58 | } | |
| 59 | item_append("Other Controls", NULL, 0, (void *)(FPTR)(IPG_OTHER + 1)); | |
| 60 | } | |
| 61 | ||
| 62 | ui_menu_input_groups::~ui_menu_input_groups() | |
| 63 | { | |
| 64 | } | |
| 65 | ||
| 66 | /*------------------------------------------------- | |
| 67 | menu_input_groups - handle the input groups | |
| 68 | menu | |
| 69 | -------------------------------------------------*/ | |
| 70 | ||
| 71 | void ui_menu_input_groups::handle() | |
| 72 | { | |
| 73 | /* process the menu */ | |
| 74 | const ui_menu_event *menu_event = process(0); | |
| 75 | if (menu_event != NULL && menu_event->iptkey == IPT_UI_SELECT) | |
| 76 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_input_general(machine(), container, int((long long)(menu_event->itemref)-1)))); | |
| 77 | } | |
| 78 | ||
| 79 | ||
| 80 | ||
| 81 | /*------------------------------------------------- | |
| 82 | menu_input_general - handle the general | |
| 83 | input menu | |
| 84 | -------------------------------------------------*/ | |
| 85 | ||
| 86 | ui_menu_input_general::ui_menu_input_general(running_machine &machine, render_container *container, int _group) : ui_menu_input(machine, container) | |
| 87 | { | |
| 88 | group = _group; | |
| 89 | } | |
| 90 | ||
| 91 | void ui_menu_input_general::populate() | |
| 92 | { | |
| 93 | input_item_data *itemlist = NULL; | |
| 94 | int suborder[SEQ_TYPE_TOTAL]; | |
| 95 | astring tempstring; | |
| 96 | int sortorder = 1; | |
| 97 | ||
| 98 | /* create a mini lookup table for sort order based on sequence type */ | |
| 99 | suborder[SEQ_TYPE_STANDARD] = 0; | |
| 100 | suborder[SEQ_TYPE_DECREMENT] = 1; | |
| 101 | suborder[SEQ_TYPE_INCREMENT] = 2; | |
| 102 | ||
| 103 | /* iterate over the input ports and add menu items */ | |
| 104 | for (input_type_entry *entry = machine().ioport().first_type(); entry != NULL; entry = entry->next()) | |
| 105 | ||
| 106 | /* add if we match the group and we have a valid name */ | |
| 107 | if (entry->group() == group && entry->name() != NULL && entry->name()[0] != 0) | |
| 108 | { | |
| 109 | input_seq_type seqtype; | |
| 110 | ||
| 111 | /* loop over all sequence types */ | |
| 112 | sortorder++; | |
| 113 | for (seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; seqtype++) | |
| 114 | { | |
| 115 | /* build an entry for the standard sequence */ | |
| 116 | input_item_data *item = (input_item_data *)m_pool_alloc(sizeof(*item)); | |
| 117 | memset(item, 0, sizeof(*item)); | |
| 118 | item->ref = entry; | |
| 119 | if(pollingitem && pollingref == entry && pollingseq == seqtype) | |
| 120 | pollingitem = item; | |
| 121 | item->seqtype = seqtype; | |
| 122 | item->seq = machine().ioport().type_seq(entry->type(), entry->player(), seqtype); | |
| 123 | item->defseq = &entry->defseq(seqtype); | |
| 124 | item->sortorder = sortorder * 4 + suborder[seqtype]; | |
| 125 | item->type = ioport_manager::type_is_analog(entry->type()) ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; | |
| 126 | item->name = entry->name(); | |
| 127 | item->owner_name = NULL; | |
| 128 | item->next = itemlist; | |
| 129 | itemlist = item; | |
| 130 | ||
| 131 | /* stop after one, unless we're analog */ | |
| 132 | if (item->type == INPUT_TYPE_DIGITAL) | |
| 133 | break; | |
| 134 | } | |
| 135 | } | |
| 136 | ||
| 137 | /* sort and populate the menu in a standard fashion */ | |
| 138 | populate_and_sort(itemlist); | |
| 139 | } | |
| 140 | ||
| 141 | ui_menu_input_general::~ui_menu_input_general() | |
| 142 | { | |
| 143 | } | |
| 144 | ||
| 145 | /*------------------------------------------------- | |
| 146 | menu_input_specific - handle the game-specific | |
| 147 | input menu | |
| 148 | -------------------------------------------------*/ | |
| 149 | ||
| 150 | ui_menu_input_specific::ui_menu_input_specific(running_machine &machine, render_container *container) : ui_menu_input(machine, container) | |
| 151 | { | |
| 152 | } | |
| 153 | ||
| 154 | void ui_menu_input_specific::populate() | |
| 155 | { | |
| 156 | input_item_data *itemlist = NULL; | |
| 157 | ioport_field *field; | |
| 158 | ioport_port *port; | |
| 159 | int suborder[SEQ_TYPE_TOTAL]; | |
| 160 | astring tempstring; | |
| 161 | ||
| 162 | /* create a mini lookup table for sort order based on sequence type */ | |
| 163 | suborder[SEQ_TYPE_STANDARD] = 0; | |
| 164 | suborder[SEQ_TYPE_DECREMENT] = 1; | |
| 165 | suborder[SEQ_TYPE_INCREMENT] = 2; | |
| 166 | ||
| 167 | /* iterate over the input ports and add menu items */ | |
| 168 | for (port = machine().ioport().first_port(); port != NULL; port = port->next()) | |
| 169 | for (field = port->first_field(); field != NULL; field = field->next()) | |
| 170 | { | |
| 171 | const char *name = field->name(); | |
| 172 | ||
| 173 | /* add if we match the group and we have a valid name */ | |
| 174 | if (name != NULL && field->enabled() && | |
| 175 | ((field->type() == IPT_OTHER && field->name() != NULL) || machine().ioport().type_group(field->type(), field->player()) != IPG_INVALID)) | |
| 176 | { | |
| 177 | input_seq_type seqtype; | |
| 178 | UINT32 sortorder; | |
| 179 | ||
| 180 | /* determine the sorting order */ | |
| 181 | if (field->type() >= IPT_START1 && field->type() < IPT_ANALOG_LAST) | |
| 182 | { | |
| 183 | sortorder = (field->type() << 2) | (field->player() << 12); | |
| 184 | if (strcmp(field->device().tag(), ":")) | |
| 185 | sortorder |= 0x10000; | |
| 186 | } | |
| 187 | else | |
| 188 | sortorder = field->type() | 0xf000; | |
| 189 | ||
| 190 | /* loop over all sequence types */ | |
| 191 | for (seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; seqtype++) | |
| 192 | { | |
| 193 | /* build an entry for the standard sequence */ | |
| 194 | input_item_data *item = (input_item_data *)m_pool_alloc(sizeof(*item)); | |
| 195 | memset(item, 0, sizeof(*item)); | |
| 196 | item->ref = field; | |
| 197 | item->seqtype = seqtype; | |
| 198 | if(pollingitem && pollingref == field && pollingseq == seqtype) | |
| 199 | pollingitem = item; | |
| 200 | item->seq = field->seq(seqtype); | |
| 201 | item->defseq = &field->defseq(seqtype); | |
| 202 | item->sortorder = sortorder + suborder[seqtype]; | |
| 203 | item->type = field->is_analog() ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; | |
| 204 | item->name = name; | |
| 205 | item->owner_name = field->device().tag(); | |
| 206 | item->next = itemlist; | |
| 207 | itemlist = item; | |
| 208 | ||
| 209 | /* stop after one, unless we're analog */ | |
| 210 | if (item->type == INPUT_TYPE_DIGITAL) | |
| 211 | break; | |
| 212 | } | |
| 213 | } | |
| 214 | } | |
| 215 | ||
| 216 | /* sort and populate the menu in a standard fashion */ | |
| 217 | populate_and_sort(itemlist); | |
| 218 | } | |
| 219 | ||
| 220 | ui_menu_input_specific::~ui_menu_input_specific() | |
| 221 | { | |
| 222 | } | |
| 223 | ||
| 224 | /*------------------------------------------------- | |
| 225 | menu_input - display a menu for inputs | |
| 226 | -------------------------------------------------*/ | |
| 227 | ui_menu_input::ui_menu_input(running_machine &machine, render_container *container) : ui_menu(machine, container) | |
| 228 | { | |
| 229 | pollingitem = 0; | |
| 230 | pollingref = 0; | |
| 231 | pollingseq = SEQ_TYPE_STANDARD; | |
| 232 | } | |
| 233 | ||
| 234 | ui_menu_input::~ui_menu_input() | |
| 235 | { | |
| 236 | } | |
| 237 | ||
| 238 | /*------------------------------------------------- | |
| 239 | toggle_none_default - toggle between "NONE" | |
| 240 | and the default item | |
| 241 | -------------------------------------------------*/ | |
| 242 | ||
| 243 | void ui_menu_input::toggle_none_default(input_seq &selected_seq, input_seq &original_seq, const input_seq &selected_defseq) | |
| 244 | { | |
| 245 | /* if we used to be "none", toggle to the default value */ | |
| 246 | if (original_seq.length() == 0) | |
| 247 | selected_seq = selected_defseq; | |
| 248 | ||
| 249 | /* otherwise, toggle to "none" */ | |
| 250 | else | |
| 251 | selected_seq.reset(); | |
| 252 | } | |
| 253 | ||
| 254 | void ui_menu_input::handle() | |
| 255 | { | |
| 256 | input_item_data *seqchangeditem = NULL; | |
| 257 | const ui_menu_event *menu_event; | |
| 258 | int invalidate = false; | |
| 259 | ||
| 260 | /* process the menu */ | |
| 261 | menu_event = process((pollingitem != NULL) ? UI_MENU_PROCESS_NOKEYS : 0); | |
| 262 | ||
| 263 | /* if we are polling, handle as a special case */ | |
| 264 | if (pollingitem != NULL) | |
| 265 | { | |
| 266 | input_item_data *item = pollingitem; | |
| 267 | input_seq newseq; | |
| 268 | ||
| 269 | /* if UI_CANCEL is pressed, abort */ | |
| 270 | if (ui_input_pressed(machine(), IPT_UI_CANCEL)) | |
| 271 | { | |
| 272 | pollingitem = NULL; | |
| 273 | record_next = false; | |
| 274 | toggle_none_default(item->seq, starting_seq, *item->defseq); | |
| 275 | seqchangeditem = item; | |
| 276 | } | |
| 277 | ||
| 278 | /* poll again; if finished, update the sequence */ | |
| 279 | if (machine().input().seq_poll()) | |
| 280 | { | |
| 281 | pollingitem = NULL; | |
| 282 | record_next = true; | |
| 283 | item->seq = machine().input().seq_poll_final(); | |
| 284 | seqchangeditem = item; | |
| 285 | } | |
| 286 | } | |
| 287 | ||
| 288 | /* otherwise, handle the events */ | |
| 289 | else if (menu_event != NULL && menu_event->itemref != NULL) | |
| 290 | { | |
| 291 | input_item_data *item = (input_item_data *)menu_event->itemref; | |
| 292 | switch (menu_event->iptkey) | |
| 293 | { | |
| 294 | /* an item was selected: begin polling */ | |
| 295 | case IPT_UI_SELECT: | |
| 296 | pollingitem = item; | |
| 297 | last_sortorder = item->sortorder; | |
| 298 | starting_seq = item->seq; | |
| 299 | machine().input().seq_poll_start((item->type == INPUT_TYPE_ANALOG) ? ITEM_CLASS_ABSOLUTE : ITEM_CLASS_SWITCH, record_next ? &item->seq : NULL); | |
| 300 | invalidate = true; | |
| 301 | break; | |
| 302 | ||
| 303 | /* if the clear key was pressed, reset the selected item */ | |
| 304 | case IPT_UI_CLEAR: | |
| 305 | toggle_none_default(item->seq, item->seq, *item->defseq); | |
| 306 | record_next = false; | |
| 307 | seqchangeditem = item; | |
| 308 | break; | |
| 309 | } | |
| 310 | ||
| 311 | /* if the selection changed, reset the "record next" flag */ | |
| 312 | if (item->sortorder != last_sortorder) | |
| 313 | record_next = false; | |
| 314 | last_sortorder = item->sortorder; | |
| 315 | } | |
| 316 | ||
| 317 | /* if the sequence changed, update it */ | |
| 318 | if (seqchangeditem != NULL) | |
| 319 | { | |
| 320 | update_input(seqchangeditem); | |
| 321 | ||
| 322 | /* invalidate the menu to force an update */ | |
| 323 | invalidate = true; | |
| 324 | } | |
| 325 | ||
| 326 | /* if the menu is invalidated, clear it now */ | |
| 327 | if (invalidate) | |
| 328 | { | |
| 329 | pollingref = NULL; | |
| 330 | if (pollingitem != NULL) | |
| 331 | { | |
| 332 | pollingref = pollingitem->ref; | |
| 333 | pollingseq = pollingitem->seqtype; | |
| 334 | } | |
| 335 | reset(UI_MENU_RESET_REMEMBER_POSITION); | |
| 336 | } | |
| 337 | } | |
| 338 | ||
| 339 | void ui_menu_input_general::update_input(struct input_item_data *seqchangeditem) | |
| 340 | { | |
| 341 | const input_type_entry *entry = (const input_type_entry *)seqchangeditem->ref; | |
| 342 | machine().ioport().set_type_seq(entry->type(), entry->player(), seqchangeditem->seqtype, seqchangeditem->seq); | |
| 343 | } | |
| 344 | ||
| 345 | void ui_menu_input_specific::update_input(struct input_item_data *seqchangeditem) | |
| 346 | { | |
| 347 | ioport_field::user_settings settings; | |
| 348 | ||
| 349 | ((ioport_field *)seqchangeditem->ref)->get_user_settings(settings); | |
| 350 | settings.seq[seqchangeditem->seqtype] = seqchangeditem->seq; | |
| 351 | ((ioport_field *)seqchangeditem->ref)->set_user_settings(settings); | |
| 352 | } | |
| 353 | ||
| 354 | ||
| 355 | /*------------------------------------------------- | |
| 356 | menu_input_compare_items - compare two | |
| 357 | items for quicksort | |
| 358 | -------------------------------------------------*/ | |
| 359 | ||
| 360 | int ui_menu_input::compare_items(const void *i1, const void *i2) | |
| 361 | { | |
| 362 | const input_item_data * const *data1 = (const input_item_data * const *)i1; | |
| 363 | const input_item_data * const *data2 = (const input_item_data * const *)i2; | |
| 364 | if ((*data1)->sortorder < (*data2)->sortorder) | |
| 365 | return -1; | |
| 366 | if ((*data1)->sortorder > (*data2)->sortorder) | |
| 367 | return 1; | |
| 368 | return 0; | |
| 369 | } | |
| 370 | ||
| 371 | ||
| 372 | /*------------------------------------------------- | |
| 373 | menu_input_populate_and_sort - take a list | |
| 374 | of input_item_data objects and build up the | |
| 375 | menu from them | |
| 376 | -------------------------------------------------*/ | |
| 377 | ||
| 378 | void ui_menu_input::populate_and_sort(input_item_data *itemlist) | |
| 379 | { | |
| 380 | const char *nameformat[INPUT_TYPE_TOTAL] = { 0 }; | |
| 381 | input_item_data **itemarray, *item; | |
| 382 | int numitems = 0, curitem; | |
| 383 | astring text; | |
| 384 | astring subtext; | |
| 385 | astring prev_owner; | |
| 386 | bool first_entry = true; | |
| 387 | ||
| 388 | /* create a mini lookup table for name format based on type */ | |
| 389 | nameformat[INPUT_TYPE_DIGITAL] = "%s"; | |
| 390 | nameformat[INPUT_TYPE_ANALOG] = "%s Analog"; | |
| 391 | nameformat[INPUT_TYPE_ANALOG_INC] = "%s Analog Inc"; | |
| 392 | nameformat[INPUT_TYPE_ANALOG_DEC] = "%s Analog Dec"; | |
| 393 | ||
| 394 | /* first count the number of items */ | |
| 395 | for (item = itemlist; item != NULL; item = item->next) | |
| 396 | numitems++; | |
| 397 | ||
| 398 | /* now allocate an array of items and fill it up */ | |
| 399 | itemarray = (input_item_data **)m_pool_alloc(sizeof(*itemarray) * numitems); | |
| 400 | for (item = itemlist, curitem = 0; item != NULL; item = item->next) | |
| 401 | itemarray[curitem++] = item; | |
| 402 | ||
| 403 | /* sort it */ | |
| 404 | qsort(itemarray, numitems, sizeof(*itemarray), compare_items); | |
| 405 | ||
| 406 | /* build the menu */ | |
| 407 | for (curitem = 0; curitem < numitems; curitem++) | |
| 408 | { | |
| 409 | UINT32 flags = 0; | |
| 410 | ||
| 411 | /* generate the name of the item itself, based off the base name and the type */ | |
| 412 | item = itemarray[curitem]; | |
| 413 | assert(nameformat[item->type] != NULL); | |
| 414 | ||
| 415 | if (strcmp(item->owner_name, prev_owner.cstr()) != 0) | |
| 416 | { | |
| 417 | if (first_entry) | |
| 418 | first_entry = false; | |
| 419 | else | |
| 420 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 421 | text.printf("[root%s]", item->owner_name); | |
| 422 | item_append(text, NULL, 0, NULL); | |
| 423 | prev_owner.cpy(item->owner_name); | |
| 424 | } | |
| 425 | ||
| 426 | text.printf(nameformat[item->type], item->name); | |
| 427 | ||
| 428 | /* if we're polling this item, use some spaces with left/right arrows */ | |
| 429 | if (pollingref == item->ref) | |
| 430 | { | |
| 431 | subtext.cpy(" "); | |
| 432 | flags |= MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW; | |
| 433 | } | |
| 434 | ||
| 435 | /* otherwise, generate the sequence name and invert it if different from the default */ | |
| 436 | else | |
| 437 | { | |
| 438 | machine().input().seq_name(subtext, item->seq); | |
| 439 | flags |= (item->seq != *item->defseq) ? MENU_FLAG_INVERT : 0; | |
| 440 | } | |
| 441 | ||
| 442 | /* add the item */ | |
| 443 | item_append(text, subtext, flags, item); | |
| 444 | } | |
| 445 | } | |
| 446 | ||
| 447 | ||
| 448 | /*------------------------------------------------- | |
| 449 | menu_settings_dip_switches - handle the DIP | |
| 450 | switches menu | |
| 451 | -------------------------------------------------*/ | |
| 452 | ||
| 453 | ui_menu_settings_dip_switches::ui_menu_settings_dip_switches(running_machine &machine, render_container *container) : ui_menu_settings(machine, container, IPT_DIPSWITCH) | |
| 454 | { | |
| 455 | } | |
| 456 | ||
| 457 | ui_menu_settings_dip_switches::~ui_menu_settings_dip_switches() | |
| 458 | { | |
| 459 | } | |
| 460 | ||
| 461 | /*------------------------------------------------- | |
| 462 | menu_settings_driver_config - handle the | |
| 463 | driver config menu | |
| 464 | -------------------------------------------------*/ | |
| 465 | ||
| 466 | ui_menu_settings_driver_config::ui_menu_settings_driver_config(running_machine &machine, render_container *container) : ui_menu_settings(machine, container, IPT_CONFIG) | |
| 467 | { | |
| 468 | } | |
| 469 | ||
| 470 | ui_menu_settings_driver_config::~ui_menu_settings_driver_config() | |
| 471 | { | |
| 472 | } | |
| 473 | ||
| 474 | /*------------------------------------------------- | |
| 475 | menu_settings_common - handle one of the | |
| 476 | switches menus | |
| 477 | -------------------------------------------------*/ | |
| 478 | ||
| 479 | void ui_menu_settings::handle() | |
| 480 | { | |
| 481 | // process the menu | |
| 482 | const ui_menu_event *menu_event = process(0); | |
| 483 | ||
| 484 | // handle events | |
| 485 | if (menu_event != NULL && menu_event->itemref != NULL) | |
| 486 | { | |
| 487 | // reset | |
| 488 | if ((FPTR)menu_event->itemref == 1) | |
| 489 | { | |
| 490 | if (menu_event->iptkey == IPT_UI_SELECT) | |
| 491 | machine().schedule_hard_reset(); | |
| 492 | } | |
| 493 | // actual settings | |
| 494 | else | |
| 495 | { | |
| 496 | ioport_field *field = (ioport_field *)menu_event->itemref; | |
| 497 | ioport_field::user_settings settings; | |
| 498 | int changed = false; | |
| 499 | ||
| 500 | switch (menu_event->iptkey) | |
| 501 | { | |
| 502 | /* if selected, reset to default value */ | |
| 503 | case IPT_UI_SELECT: | |
| 504 | field->get_user_settings(settings); | |
| 505 | settings.value = field->defvalue(); | |
| 506 | field->set_user_settings(settings); | |
| 507 | changed = true; | |
| 508 | break; | |
| 509 | ||
| 510 | /* left goes to previous setting */ | |
| 511 | case IPT_UI_LEFT: | |
| 512 | field->select_previous_setting(); | |
| 513 | changed = true; | |
| 514 | break; | |
| 515 | ||
| 516 | /* right goes to next setting */ | |
| 517 | case IPT_UI_RIGHT: | |
| 518 | field->select_next_setting(); | |
| 519 | changed = true; | |
| 520 | break; | |
| 521 | } | |
| 522 | ||
| 523 | /* if anything changed, rebuild the menu, trying to stay on the same field */ | |
| 524 | if (changed) | |
| 525 | reset(UI_MENU_RESET_REMEMBER_REF); | |
| 526 | } | |
| 527 | } | |
| 528 | } | |
| 529 | ||
| 530 | ||
| 531 | /*------------------------------------------------- | |
| 532 | menu_settings_populate - populate one of the | |
| 533 | switches menus | |
| 534 | -------------------------------------------------*/ | |
| 535 | ||
| 536 | ui_menu_settings::ui_menu_settings(running_machine &machine, render_container *container, UINT32 _type) : ui_menu(machine, container) | |
| 537 | { | |
| 538 | type = _type; | |
| 539 | } | |
| 540 | ||
| 541 | void ui_menu_settings::populate() | |
| 542 | { | |
| 543 | ioport_field *field; | |
| 544 | ioport_port *port; | |
| 545 | dip_descriptor **diplist_tailptr; | |
| 546 | astring prev_owner; | |
| 547 | bool first_entry = true; | |
| 548 | ||
| 549 | /* reset the dip switch tracking */ | |
| 550 | dipcount = 0; | |
| 551 | diplist = NULL; | |
| 552 | diplist_tailptr = &diplist; | |
| 553 | ||
| 554 | /* loop over input ports and set up the current values */ | |
| 555 | for (port = machine().ioport().first_port(); port != NULL; port = port->next()) | |
| 556 | for (field = port->first_field(); field != NULL; field = field->next()) | |
| 557 | if (field->type() == type && field->enabled()) | |
| 558 | { | |
| 559 | UINT32 flags = 0; | |
| 560 | astring name; | |
| 561 | ||
| 562 | /* set the left/right flags appropriately */ | |
| 563 | if (field->has_previous_setting()) | |
| 564 | flags |= MENU_FLAG_LEFT_ARROW; | |
| 565 | if (field->has_next_setting()) | |
| 566 | flags |= MENU_FLAG_RIGHT_ARROW; | |
| 567 | ||
| 568 | /* add the menu item */ | |
| 569 | if (strcmp(field->device().tag(), prev_owner.cstr()) != 0) | |
| 570 | { | |
| 571 | if (first_entry) | |
| 572 | first_entry = false; | |
| 573 | else | |
| 574 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 575 | name.printf("[root%s]", field->device().tag()); | |
| 576 | item_append(name, NULL, 0, NULL); | |
| 577 | prev_owner.cpy(field->device().tag()); | |
| 578 | } | |
| 579 | ||
| 580 | name.cpy(field->name()); | |
| 581 | ||
| 582 | item_append(name, field->setting_name(), flags, (void *)field); | |
| 583 | ||
| 584 | /* for DIP switches, build up the model */ | |
| 585 | if (type == IPT_DIPSWITCH && field->first_diplocation() != NULL) | |
| 586 | { | |
| 587 | const ioport_diplocation *diploc; | |
| 588 | ioport_field::user_settings settings; | |
| 589 | UINT32 accummask = field->mask(); | |
| 590 | ||
| 591 | /* get current settings */ | |
| 592 | field->get_user_settings(settings); | |
| 593 | ||
| 594 | /* iterate over each bit in the field */ | |
| 595 | for (diploc = field->first_diplocation(); diploc != NULL; diploc = diploc->next()) | |
| 596 | { | |
| 597 | UINT32 mask = accummask & ~(accummask - 1); | |
| 598 | dip_descriptor *dip; | |
| 599 | ||
| 600 | /* find the matching switch name */ | |
| 601 | for (dip = diplist; dip != NULL; dip = dip->next) | |
| 602 | if (strcmp(dip->name, diploc->name()) == 0) | |
| 603 | break; | |
| 604 | ||
| 605 | /* allocate new if none */ | |
| 606 | if (dip == NULL) | |
| 607 | { | |
| 608 | dip = (dip_descriptor *)m_pool_alloc(sizeof(*dip)); | |
| 609 | dip->next = NULL; | |
| 610 | dip->name = diploc->name(); | |
| 611 | dip->mask = dip->state = 0; | |
| 612 | *diplist_tailptr = dip; | |
| 613 | diplist_tailptr = &dip->next; | |
| 614 | dipcount++; | |
| 615 | } | |
| 616 | ||
| 617 | /* apply the bits */ | |
| 618 | dip->mask |= 1 << (diploc->number() - 1); | |
| 619 | if (((settings.value & mask) != 0 && !diploc->inverted()) || ((settings.value & mask) == 0 && diploc->inverted())) | |
| 620 | dip->state |= 1 << (diploc->number() - 1); | |
| 621 | ||
| 622 | /* clear the relevant bit in the accumulated mask */ | |
| 623 | accummask &= ~mask; | |
| 624 | } | |
| 625 | } | |
| 626 | } | |
| 627 | if (type == IPT_DIPSWITCH) | |
| 628 | custombottom = dipcount ? dipcount * (DIP_SWITCH_HEIGHT + DIP_SWITCH_SPACING) + DIP_SWITCH_SPACING : 0; | |
| 629 | ||
| 630 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 631 | item_append("Reset", NULL, 0, (void *)1); | |
| 632 | } | |
| 633 | ||
| 634 | ui_menu_settings::~ui_menu_settings() | |
| 635 | { | |
| 636 | } | |
| 637 | ||
| 638 | /*------------------------------------------------- | |
| 639 | menu_settings_custom_render - perform our special | |
| 640 | rendering | |
| 641 | -------------------------------------------------*/ | |
| 642 | ||
| 643 | void ui_menu_settings_dip_switches::custom_render(void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2) | |
| 644 | { | |
| 645 | // catch if no diploc has to be drawn | |
| 646 | if (bottom == 0) | |
| 647 | return; | |
| 648 | ||
| 649 | // add borders | |
| 650 | y1 = y2 + UI_BOX_TB_BORDER; | |
| 651 | y2 = y1 + bottom; | |
| 652 | ||
| 653 | // draw extra menu area | |
| 654 | machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR); | |
| 655 | y1 += (float)DIP_SWITCH_SPACING; | |
| 656 | ||
| 657 | // iterate over DIP switches | |
| 658 | for (dip_descriptor *dip = diplist; dip != NULL; dip = dip->next) | |
| 659 | { | |
| 660 | const ioport_diplocation *diploc; | |
| 661 | UINT32 selectedmask = 0; | |
| 662 | ||
| 663 | // determine the mask of selected bits | |
| 664 | if ((FPTR)selectedref != 1) | |
| 665 | { | |
| 666 | ioport_field *field = (ioport_field *)selectedref; | |
| 667 | ||
| 668 | if (field != NULL && field->first_diplocation() != NULL) | |
| 669 | for (diploc = field->first_diplocation(); diploc != NULL; diploc = diploc->next()) | |
| 670 | if (strcmp(dip->name, diploc->name()) == 0) | |
| 671 | selectedmask |= 1 << (diploc->number() - 1); | |
| 672 | } | |
| 673 | ||
| 674 | // draw one switch | |
| 675 | custom_render_one(x1, y1, x2, y1 + DIP_SWITCH_HEIGHT, dip, selectedmask); | |
| 676 | y1 += (float)(DIP_SWITCH_SPACING + DIP_SWITCH_HEIGHT); | |
| 677 | } | |
| 678 | } | |
| 679 | ||
| 680 | ||
| 681 | /*------------------------------------------------- | |
| 682 | menu_settings_custom_render_one - draw a single | |
| 683 | DIP switch | |
| 684 | -------------------------------------------------*/ | |
| 685 | ||
| 686 | void ui_menu_settings_dip_switches::custom_render_one(float x1, float y1, float x2, float y2, const dip_descriptor *dip, UINT32 selectedmask) | |
| 687 | { | |
| 688 | float switch_field_width = SINGLE_TOGGLE_SWITCH_FIELD_WIDTH * container->manager().ui_aspect(); | |
| 689 | float switch_width = SINGLE_TOGGLE_SWITCH_WIDTH * container->manager().ui_aspect(); | |
| 690 | int numtoggles, toggle; | |
| 691 | float switch_toggle_gap; | |
| 692 | float y1_off, y1_on; | |
| 693 | ||
| 694 | /* determine the number of toggles in the DIP */ | |
| 695 | numtoggles = 32 - count_leading_zeros(dip->mask); | |
| 696 | ||
| 697 | /* center based on the number of switches */ | |
| 698 | x1 += (x2 - x1 - numtoggles * switch_field_width) / 2; | |
| 699 | ||
| 700 | /* draw the dip switch name */ | |
| 701 | machine().ui().draw_text_full( container, | |
| 702 | dip->name, | |
| 703 | 0, | |
| 704 | y1 + (DIP_SWITCH_HEIGHT - UI_TARGET_FONT_HEIGHT) / 2, | |
| 705 | x1 - machine().ui().get_string_width(" "), | |
| 706 | JUSTIFY_RIGHT, | |
| 707 | WRAP_NEVER, | |
| 708 | DRAW_NORMAL, | |
| 709 | UI_TEXT_COLOR, | |
| 710 | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA), | |
| 711 | NULL , | |
| 712 | NULL); | |
| 713 | ||
| 714 | /* compute top and bottom for on and off positions */ | |
| 715 | switch_toggle_gap = ((DIP_SWITCH_HEIGHT/2) - SINGLE_TOGGLE_SWITCH_HEIGHT)/2; | |
| 716 | y1_off = y1 + UI_LINE_WIDTH + switch_toggle_gap; | |
| 717 | y1_on = y1 + DIP_SWITCH_HEIGHT/2 + switch_toggle_gap; | |
| 718 | ||
| 719 | /* iterate over toggles */ | |
| 720 | for (toggle = 0; toggle < numtoggles; toggle++) | |
| 721 | { | |
| 722 | float innerx1; | |
| 723 | ||
| 724 | /* first outline the switch */ | |
| 725 | machine().ui().draw_outlined_box(container, x1, y1, x1 + switch_field_width, y2, UI_BACKGROUND_COLOR); | |
| 726 | ||
| 727 | /* compute x1/x2 for the inner filled in switch */ | |
| 728 | innerx1 = x1 + (switch_field_width - switch_width) / 2; | |
| 729 | ||
| 730 | /* see if the switch is actually used */ | |
| 731 | if (dip->mask & (1 << toggle)) | |
| 732 | { | |
| 733 | float innery1 = (dip->state & (1 << toggle)) ? y1_on : y1_off; | |
| 734 | container->add_rect(innerx1, innery1, innerx1 + switch_width, innery1 + SINGLE_TOGGLE_SWITCH_HEIGHT, | |
| 735 | (selectedmask & (1 << toggle)) ? UI_DIPSW_COLOR : UI_TEXT_COLOR, | |
| 736 | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); | |
| 737 | } | |
| 738 | else | |
| 739 | { | |
| 740 | container->add_rect(innerx1, y1_off, innerx1 + switch_width, y1_on + SINGLE_TOGGLE_SWITCH_HEIGHT, | |
| 741 | UI_UNAVAILABLE_COLOR, | |
| 742 | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); | |
| 743 | } | |
| 744 | ||
| 745 | /* advance to the next switch */ | |
| 746 | x1 += switch_field_width; | |
| 747 | } | |
| 748 | } | |
| 749 | ||
| 750 | ||
| 751 | /*------------------------------------------------- | |
| 752 | menu_analog - handle the analog settings menu | |
| 753 | -------------------------------------------------*/ | |
| 754 | ||
| 755 | void ui_menu_analog::handle() | |
| 756 | { | |
| 757 | /* process the menu */ | |
| 758 | const ui_menu_event *menu_event = process(UI_MENU_PROCESS_LR_REPEAT); | |
| 759 | ||
| 760 | /* handle events */ | |
| 761 | if (menu_event != NULL && menu_event->itemref != NULL) | |
| 762 | { | |
| 763 | analog_item_data *data = (analog_item_data *)menu_event->itemref; | |
| 764 | int newval = data->cur; | |
| 765 | ||
| 766 | switch (menu_event->iptkey) | |
| 767 | { | |
| 768 | /* if selected, reset to default value */ | |
| 769 | case IPT_UI_SELECT: | |
| 770 | newval = data->defvalue; | |
| 771 | break; | |
| 772 | ||
| 773 | /* left decrements */ | |
| 774 | case IPT_UI_LEFT: | |
| 775 | newval -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; | |
| 776 | break; | |
| 777 | ||
| 778 | /* right increments */ | |
| 779 | case IPT_UI_RIGHT: | |
| 780 | newval += machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; | |
| 781 | break; | |
| 782 | } | |
| 783 | ||
| 784 | /* clamp to range */ | |
| 785 | if (newval < data->min) | |
| 786 | newval = data->min; | |
| 787 | if (newval > data->max) | |
| 788 | newval = data->max; | |
| 789 | ||
| 790 | /* if things changed, update */ | |
| 791 | if (newval != data->cur) | |
| 792 | { | |
| 793 | ioport_field::user_settings settings; | |
| 794 | ||
| 795 | /* get the settings and set the new value */ | |
| 796 | data->field->get_user_settings(settings); | |
| 797 | switch (data->type) | |
| 798 | { | |
| 799 | case ANALOG_ITEM_KEYSPEED: settings.delta = newval; break; | |
| 800 | case ANALOG_ITEM_CENTERSPEED: settings.centerdelta = newval; break; | |
| 801 | case ANALOG_ITEM_REVERSE: settings.reverse = newval; break; | |
| 802 | case ANALOG_ITEM_SENSITIVITY: settings.sensitivity = newval; break; | |
| 803 | } | |
| 804 | data->field->set_user_settings(settings); | |
| 805 | ||
| 806 | /* rebuild the menu */ | |
| 807 | reset(UI_MENU_RESET_REMEMBER_POSITION); | |
| 808 | } | |
| 809 | } | |
| 810 | } | |
| 811 | ||
| 812 | ||
| 813 | /*------------------------------------------------- | |
| 814 | menu_analog_populate - populate the analog | |
| 815 | settings menu | |
| 816 | -------------------------------------------------*/ | |
| 817 | ||
| 818 | ui_menu_analog::ui_menu_analog(running_machine &machine, render_container *container) : ui_menu(machine, container) | |
| 819 | { | |
| 820 | } | |
| 821 | ||
| 822 | void ui_menu_analog::populate() | |
| 823 | { | |
| 824 | ioport_field *field; | |
| 825 | ioport_port *port; | |
| 826 | astring text; | |
| 827 | astring subtext; | |
| 828 | astring prev_owner; | |
| 829 | bool first_entry = true; | |
| 830 | ||
| 831 | /* loop over input ports and add the items */ | |
| 832 | for (port = machine().ioport().first_port(); port != NULL; port = port->next()) | |
| 833 | for (field = port->first_field(); field != NULL; field = field->next()) | |
| 834 | if (field->is_analog() && field->enabled()) | |
| 835 | { | |
| 836 | ioport_field::user_settings settings; | |
| 837 | int use_autocenter = false; | |
| 838 | int type; | |
| 839 | ||
| 840 | /* based on the type, determine if we enable autocenter */ | |
| 841 | switch (field->type()) | |
| 842 | { | |
| 843 | case IPT_POSITIONAL: | |
| 844 | case IPT_POSITIONAL_V: | |
| 845 | if (field->analog_wraps()) | |
| 846 | break; | |
| 847 | ||
| 848 | case IPT_AD_STICK_X: | |
| 849 | case IPT_AD_STICK_Y: | |
| 850 | case IPT_AD_STICK_Z: | |
| 851 | case IPT_PADDLE: | |
| 852 | case IPT_PADDLE_V: | |
| 853 | case IPT_PEDAL: | |
| 854 | case IPT_PEDAL2: | |
| 855 | case IPT_PEDAL3: | |
| 856 | use_autocenter = true; | |
| 857 | break; | |
| 858 | ||
| 859 | default: | |
| 860 | break; | |
| 861 | } | |
| 862 | ||
| 863 | /* get the user settings */ | |
| 864 | field->get_user_settings(settings); | |
| 865 | ||
| 866 | /* iterate over types */ | |
| 867 | for (type = 0; type < ANALOG_ITEM_COUNT; type++) | |
| 868 | if (type != ANALOG_ITEM_CENTERSPEED || use_autocenter) | |
| 869 | { | |
| 870 | analog_item_data *data; | |
| 871 | UINT32 flags = 0; | |
| 872 | astring name; | |
| 873 | if (strcmp(field->device().tag(), prev_owner.cstr()) != 0) | |
| 874 | { | |
| 875 | if (first_entry) | |
| 876 | first_entry = false; | |
| 877 | else | |
| 878 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 879 | name.printf("[root%s]", field->device().tag()); | |
| 880 | item_append(name, NULL, 0, NULL); | |
| 881 | prev_owner.cpy(field->device().tag()); | |
| 882 | } | |
| 883 | ||
| 884 | name.cpy(field->name()); | |
| 885 | ||
| 886 | /* allocate a data item for tracking what this menu item refers to */ | |
| 887 | data = (analog_item_data *)m_pool_alloc(sizeof(*data)); | |
| 888 | data->field = field; | |
| 889 | data->type = type; | |
| 890 | ||
| 891 | /* determine the properties of this item */ | |
| 892 | switch (type) | |
| 893 | { | |
| 894 | default: | |
| 895 | case ANALOG_ITEM_KEYSPEED: | |
| 896 | text.printf("%s Digital Speed", name.cstr()); | |
| 897 | subtext.printf("%d", settings.delta); | |
| 898 | data->min = 0; | |
| 899 | data->max = 255; | |
| 900 | data->cur = settings.delta; | |
| 901 | data->defvalue = field->delta(); | |
| 902 | break; | |
| 903 | ||
| 904 | case ANALOG_ITEM_CENTERSPEED: | |
| 905 | text.printf("%s Autocenter Speed", name.cstr()); | |
| 906 | subtext.printf("%d", settings.centerdelta); | |
| 907 | data->min = 0; | |
| 908 | data->max = 255; | |
| 909 | data->cur = settings.centerdelta; | |
| 910 | data->defvalue = field->centerdelta(); | |
| 911 | break; | |
| 912 | ||
| 913 | case ANALOG_ITEM_REVERSE: | |
| 914 | text.printf("%s Reverse", name.cstr()); | |
| 915 | subtext.cpy(settings.reverse ? "On" : "Off"); | |
| 916 | data->min = 0; | |
| 917 | data->max = 1; | |
| 918 | data->cur = settings.reverse; | |
| 919 | data->defvalue = field->analog_reverse(); | |
| 920 | break; | |
| 921 | ||
| 922 | case ANALOG_ITEM_SENSITIVITY: | |
| 923 | text.printf("%s Sensitivity", name.cstr()); | |
| 924 | subtext.printf("%d", settings.sensitivity); | |
| 925 | data->min = 1; | |
| 926 | data->max = 255; | |
| 927 | data->cur = settings.sensitivity; | |
| 928 | data->defvalue = field->sensitivity(); | |
| 929 | break; | |
| 930 | } | |
| 931 | ||
| 932 | /* put on arrows */ | |
| 933 | if (data->cur > data->min) | |
| 934 | flags |= MENU_FLAG_LEFT_ARROW; | |
| 935 | if (data->cur < data->max) | |
| 936 | flags |= MENU_FLAG_RIGHT_ARROW; | |
| 937 | ||
| 938 | /* append a menu item */ | |
| 939 | item_append(text, subtext, flags, data); | |
| 940 | } | |
| 941 | } | |
| 942 | } | |
| 943 | ||
| 944 | ui_menu_analog::~ui_menu_analog() | |
| 945 | { | |
| 946 | } |
| r242899 | r242900 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | ui/inputmap.h | |
| 4 | ||
| 5 | Internal menus for input mappings. | |
| 6 | ||
| 7 | Copyright Nicola Salmoria and the MAME Team. | |
| 8 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 9 | ||
| 10 | ***************************************************************************/ | |
| 11 | ||
| 12 | #pragma once | |
| 13 | ||
| 14 | #ifndef __UI_INPUTMAP_H__ | |
| 15 | #define __UI_INPUTMAP_H__ | |
| 16 | ||
| 17 | //#include "drivenum.h" | |
| 18 | ||
| 19 | class ui_menu_input_groups : public ui_menu { | |
| 20 | public: | |
| 21 | ui_menu_input_groups(running_machine &machine, render_container *container); | |
| 22 | virtual ~ui_menu_input_groups(); | |
| 23 | virtual void populate(); | |
| 24 | virtual void handle(); | |
| 25 | }; | |
| 26 | ||
| 27 | class ui_menu_input : public ui_menu { | |
| 28 | public: | |
| 29 | ui_menu_input(running_machine &machine, render_container *container); | |
| 30 | virtual ~ui_menu_input(); | |
| 31 | virtual void handle(); | |
| 32 | ||
| 33 | protected: | |
| 34 | enum { | |
| 35 | INPUT_TYPE_DIGITAL = 0, | |
| 36 | INPUT_TYPE_ANALOG = 1, | |
| 37 | INPUT_TYPE_ANALOG_DEC = INPUT_TYPE_ANALOG + SEQ_TYPE_DECREMENT, | |
| 38 | INPUT_TYPE_ANALOG_INC = INPUT_TYPE_ANALOG + SEQ_TYPE_INCREMENT, | |
| 39 | INPUT_TYPE_TOTAL = INPUT_TYPE_ANALOG + SEQ_TYPE_TOTAL | |
| 40 | }; | |
| 41 | ||
| 42 | /* internal input menu item data */ | |
| 43 | struct input_item_data { | |
| 44 | input_item_data * next; /* pointer to next item in the list */ | |
| 45 | const void * ref; /* reference to type description for global inputs or field for game inputs */ | |
| 46 | input_seq_type seqtype; /* sequence type */ | |
| 47 | input_seq seq; /* copy of the live sequence */ | |
| 48 | const input_seq * defseq; /* pointer to the default sequence */ | |
| 49 | const char * name; /* pointer to the base name of the item */ | |
| 50 | const char * owner_name; /* pointer to the name of the owner of the item */ | |
| 51 | UINT32 sortorder; /* sorting information */ | |
| 52 | UINT8 type; /* type of port */ | |
| 53 | }; | |
| 54 | ||
| 55 | void populate_and_sort(struct input_item_data *itemlist); | |
| 56 | virtual void update_input(struct input_item_data *seqchangeditem) = 0; | |
| 57 | void toggle_none_default(input_seq &selected_seq, input_seq &original_seq, const input_seq &selected_defseq); | |
| 58 | ||
| 59 | protected: | |
| 60 | const void * pollingref; | |
| 61 | input_seq_type pollingseq; | |
| 62 | input_item_data * pollingitem; | |
| 63 | ||
| 64 | private: | |
| 65 | UINT16 last_sortorder; | |
| 66 | bool record_next; | |
| 67 | input_seq starting_seq; | |
| 68 | ||
| 69 | static int compare_items(const void *i1, const void *i2); | |
| 70 | }; | |
| 71 | ||
| 72 | class ui_menu_input_general : public ui_menu_input { | |
| 73 | public: | |
| 74 | ui_menu_input_general(running_machine &machine, render_container *container, int group); | |
| 75 | virtual ~ui_menu_input_general(); | |
| 76 | virtual void populate(); | |
| 77 | ||
| 78 | protected: | |
| 79 | int group; | |
| 80 | virtual void update_input(struct input_item_data *seqchangeditem); | |
| 81 | }; | |
| 82 | ||
| 83 | class ui_menu_input_specific : public ui_menu_input { | |
| 84 | public: | |
| 85 | ui_menu_input_specific(running_machine &machine, render_container *container); | |
| 86 | virtual ~ui_menu_input_specific(); | |
| 87 | virtual void populate(); | |
| 88 | ||
| 89 | protected: | |
| 90 | virtual void update_input(struct input_item_data *seqchangeditem); | |
| 91 | }; | |
| 92 | ||
| 93 | class ui_menu_settings : public ui_menu { | |
| 94 | public: | |
| 95 | ui_menu_settings(running_machine &machine, render_container *container, UINT32 type); | |
| 96 | virtual ~ui_menu_settings(); | |
| 97 | virtual void populate(); | |
| 98 | virtual void handle(); | |
| 99 | ||
| 100 | protected: | |
| 101 | /* DIP switch descriptor */ | |
| 102 | struct dip_descriptor { | |
| 103 | dip_descriptor * next; | |
| 104 | const char * name; | |
| 105 | UINT32 mask; | |
| 106 | UINT32 state; | |
| 107 | }; | |
| 108 | ||
| 109 | dip_descriptor * diplist; | |
| 110 | int dipcount; | |
| 111 | int type; | |
| 112 | }; | |
| 113 | ||
| 114 | class ui_menu_settings_dip_switches : public ui_menu_settings { | |
| 115 | public: | |
| 116 | ui_menu_settings_dip_switches(running_machine &machine, render_container *container); | |
| 117 | virtual ~ui_menu_settings_dip_switches(); | |
| 118 | ||
| 119 | virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2); | |
| 120 | private: | |
| 121 | void custom_render_one(float x1, float y1, float x2, float y2, const dip_descriptor *dip, UINT32 selectedmask); | |
| 122 | }; | |
| 123 | ||
| 124 | class ui_menu_settings_driver_config : public ui_menu_settings { | |
| 125 | public: | |
| 126 | ui_menu_settings_driver_config(running_machine &machine, render_container *container); | |
| 127 | virtual ~ui_menu_settings_driver_config(); | |
| 128 | }; | |
| 129 | ||
| 130 | class ui_menu_analog : public ui_menu { | |
| 131 | public: | |
| 132 | ui_menu_analog(running_machine &machine, render_container *container); | |
| 133 | virtual ~ui_menu_analog(); | |
| 134 | virtual void populate(); | |
| 135 | virtual void handle(); | |
| 136 | ||
| 137 | private: | |
| 138 | enum { | |
| 139 | ANALOG_ITEM_KEYSPEED = 0, | |
| 140 | ANALOG_ITEM_CENTERSPEED, | |
| 141 | ANALOG_ITEM_REVERSE, | |
| 142 | ANALOG_ITEM_SENSITIVITY, | |
| 143 | ANALOG_ITEM_COUNT | |
| 144 | }; | |
| 145 | ||
| 146 | /* internal analog menu item data */ | |
| 147 | struct analog_item_data { | |
| 148 | ioport_field *field; | |
| 149 | int type; | |
| 150 | int min, max; | |
| 151 | int cur; | |
| 152 | int defvalue; | |
| 153 | }; | |
| 154 | }; | |
| 155 | ||
| 156 | #endif /* __UI_INPUTMAP_H__ */ |
| r242899 | r242900 | |
|---|---|---|
| 19 | 19 | #include "ui/filemngr.h" |
| 20 | 20 | #include "ui/filesel.h" |
| 21 | 21 | #include "ui/barcode.h" |
| 22 | #include "ui/imginfo.h" | |
| 23 | #include "ui/inputmap.h" | |
| 22 | #include "ui/tapectrl.h" | |
| 24 | 23 | #include "ui/mainmenu.h" |
| 25 | 24 | #include "ui/miscmenu.h" |
| 25 | #include "ui/imginfo.h" | |
| 26 | 26 | #include "ui/selgame.h" |
| 27 | #include "ui/slotopt.h" | |
| 28 | #include "ui/tapectrl.h" | |
| 29 | 27 | #include "audit.h" |
| 30 | 28 | #include "crsshair.h" |
| 31 | 29 | #include <ctype.h> |
| r242899 | r242900 | |
|---|---|---|
| 24 | 24 | #include "ui/filemngr.h" |
| 25 | 25 | |
| 26 | 26 | |
| 27 | /*************************************************************************** | |
| 28 | CONSTANTS | |
| 29 | ***************************************************************************/ | |
| 30 | ||
| 31 | #define MAX_PHYSICAL_DIPS 10 | |
| 32 | #define MAX_INPUT_PORTS 32 | |
| 33 | #define MAX_BITS_PER_PORT 32 | |
| 34 | ||
| 35 | /* DIP switch rendering parameters */ | |
| 36 | #define DIP_SWITCH_HEIGHT 0.05f | |
| 37 | #define DIP_SWITCH_SPACING 0.01 | |
| 38 | #define SINGLE_TOGGLE_SWITCH_FIELD_WIDTH 0.025f | |
| 39 | #define SINGLE_TOGGLE_SWITCH_WIDTH 0.020f | |
| 40 | /* make the switch 80% of the width space and 1/2 of the switch height */ | |
| 41 | #define PERCENTAGE_OF_HALF_FIELD_USED 0.80f | |
| 42 | #define SINGLE_TOGGLE_SWITCH_HEIGHT ((DIP_SWITCH_HEIGHT / 2) * PERCENTAGE_OF_HALF_FIELD_USED) | |
| 43 | ||
| 27 | 44 | /*------------------------------------------------- |
| 28 | 45 | ui_slider_ui_handler - pushes the slider |
| 29 | 46 | menu on the stack and hands off to the |
| r242899 | r242900 | |
| 91 | 108 | |
| 92 | 109 | |
| 93 | 110 | /*------------------------------------------------- |
| 111 | ui_slot_get_current_option - returns | |
| 112 | -------------------------------------------------*/ | |
| 113 | device_slot_option *ui_menu_slot_devices::slot_get_current_option(device_slot_interface *slot) | |
| 114 | { | |
| 115 | const char *current; | |
| 116 | if (slot->fixed()) | |
| 117 | { | |
| 118 | current = slot->default_option(); | |
| 119 | } | |
| 120 | else | |
| 121 | { | |
| 122 | astring temp; | |
| 123 | current = machine().options().main_value(temp, slot->device().tag() + 1); | |
| 124 | } | |
| 125 | ||
| 126 | return slot->option(current); | |
| 127 | } | |
| 128 | ||
| 129 | /*------------------------------------------------- | |
| 130 | ui_slot_get_current_index - returns | |
| 131 | -------------------------------------------------*/ | |
| 132 | int ui_menu_slot_devices::slot_get_current_index(device_slot_interface *slot) | |
| 133 | { | |
| 134 | const device_slot_option *current = slot_get_current_option(slot); | |
| 135 | ||
| 136 | if (current != NULL) | |
| 137 | { | |
| 138 | int val = 0; | |
| 139 | for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) | |
| 140 | { | |
| 141 | if (option == current) | |
| 142 | return val; | |
| 143 | ||
| 144 | if (option->selectable()) | |
| 145 | val++; | |
| 146 | } | |
| 147 | } | |
| 148 | ||
| 149 | return -1; | |
| 150 | } | |
| 151 | ||
| 152 | /*------------------------------------------------- | |
| 153 | ui_slot_get_length - returns | |
| 154 | -------------------------------------------------*/ | |
| 155 | int ui_menu_slot_devices::slot_get_length(device_slot_interface *slot) | |
| 156 | { | |
| 157 | int val = 0; | |
| 158 | for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) | |
| 159 | if (option->selectable()) | |
| 160 | val++; | |
| 161 | ||
| 162 | return val; | |
| 163 | } | |
| 164 | ||
| 165 | /*------------------------------------------------- | |
| 166 | ui_slot_get_next - returns | |
| 167 | -------------------------------------------------*/ | |
| 168 | const char *ui_menu_slot_devices::slot_get_next(device_slot_interface *slot) | |
| 169 | { | |
| 170 | int idx = slot_get_current_index(slot); | |
| 171 | if (idx < 0) | |
| 172 | idx = 0; | |
| 173 | else | |
| 174 | idx++; | |
| 175 | ||
| 176 | if (idx >= slot_get_length(slot)) | |
| 177 | return ""; | |
| 178 | ||
| 179 | return slot_get_option(slot, idx); | |
| 180 | } | |
| 181 | ||
| 182 | /*------------------------------------------------- | |
| 183 | ui_slot_get_prev - returns | |
| 184 | -------------------------------------------------*/ | |
| 185 | const char *ui_menu_slot_devices::slot_get_prev(device_slot_interface *slot) | |
| 186 | { | |
| 187 | int idx = slot_get_current_index(slot); | |
| 188 | if (idx < 0) | |
| 189 | idx = slot_get_length(slot) - 1; | |
| 190 | else | |
| 191 | idx--; | |
| 192 | ||
| 193 | if (idx < 0) | |
| 194 | return ""; | |
| 195 | ||
| 196 | return slot_get_option(slot, idx); | |
| 197 | } | |
| 198 | ||
| 199 | /*------------------------------------------------- | |
| 200 | ui_slot_get_option - returns | |
| 201 | -------------------------------------------------*/ | |
| 202 | const char *ui_menu_slot_devices::slot_get_option(device_slot_interface *slot, int index) | |
| 203 | { | |
| 204 | if (index >= 0) | |
| 205 | { | |
| 206 | int val = 0; | |
| 207 | for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) | |
| 208 | { | |
| 209 | if (val == index) | |
| 210 | return option->name(); | |
| 211 | ||
| 212 | if (option->selectable()) | |
| 213 | val++; | |
| 214 | } | |
| 215 | } | |
| 216 | ||
| 217 | return ""; | |
| 218 | } | |
| 219 | ||
| 220 | ||
| 221 | /*------------------------------------------------- | |
| 222 | ui_set_use_natural_keyboard - specifies | |
| 223 | whether the natural keyboard is active | |
| 224 | -------------------------------------------------*/ | |
| 225 | ||
| 226 | void ui_menu_slot_devices::set_slot_device(device_slot_interface *slot, const char *val) | |
| 227 | { | |
| 228 | astring error; | |
| 229 | machine().options().set_value(slot->device().tag()+1, val, OPTION_PRIORITY_CMDLINE, error); | |
| 230 | assert(!error); | |
| 231 | } | |
| 232 | ||
| 233 | /*------------------------------------------------- | |
| 234 | menu_slot_devices_populate - populates the main | |
| 235 | slot device menu | |
| 236 | -------------------------------------------------*/ | |
| 237 | ||
| 238 | ui_menu_slot_devices::ui_menu_slot_devices(running_machine &machine, render_container *container) : ui_menu(machine, container) | |
| 239 | { | |
| 240 | } | |
| 241 | ||
| 242 | void ui_menu_slot_devices::populate() | |
| 243 | { | |
| 244 | /* cycle through all devices for this system */ | |
| 245 | slot_interface_iterator iter(machine().root_device()); | |
| 246 | for (device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) | |
| 247 | { | |
| 248 | /* record the menu item */ | |
| 249 | const device_slot_option *option = slot_get_current_option(slot); | |
| 250 | astring opt_name; | |
| 251 | if (option == NULL) | |
| 252 | opt_name.cpy("------"); | |
| 253 | else | |
| 254 | { | |
| 255 | opt_name.cpy(option->name()); | |
| 256 | if (slot->fixed() || slot_get_length(slot) == 0) | |
| 257 | opt_name.cat(" [internal]"); | |
| 258 | } | |
| 259 | ||
| 260 | item_append(slot->device().tag() + 1, opt_name, (slot->fixed() || slot_get_length(slot) == 0) ? 0 : (MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW), (void *)slot); | |
| 261 | } | |
| 262 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 263 | item_append("Reset", NULL, 0, (void *)1); | |
| 264 | } | |
| 265 | ||
| 266 | ui_menu_slot_devices::~ui_menu_slot_devices() | |
| 267 | { | |
| 268 | } | |
| 269 | ||
| 270 | /*------------------------------------------------- | |
| 271 | ui_menu_slot_devices - menu that | |
| 272 | -------------------------------------------------*/ | |
| 273 | ||
| 274 | void ui_menu_slot_devices::handle() | |
| 275 | { | |
| 276 | /* process the menu */ | |
| 277 | const ui_menu_event *menu_event = process(0); | |
| 278 | ||
| 279 | if (menu_event != NULL && menu_event->itemref != NULL) | |
| 280 | { | |
| 281 | if ((FPTR)menu_event->itemref == 1 && menu_event->iptkey == IPT_UI_SELECT) | |
| 282 | machine().schedule_hard_reset(); | |
| 283 | else if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) | |
| 284 | { | |
| 285 | device_slot_interface *slot = (device_slot_interface *)menu_event->itemref; | |
| 286 | const char *val = (menu_event->iptkey == IPT_UI_LEFT) ? slot_get_prev(slot) : slot_get_next(slot); | |
| 287 | set_slot_device(slot, val); | |
| 288 | reset(UI_MENU_RESET_REMEMBER_REF); | |
| 289 | } | |
| 290 | } | |
| 291 | } | |
| 292 | ||
| 293 | /*------------------------------------------------- | |
| 94 | 294 | ui_menu_bios_selection - populates the main |
| 95 | 295 | bios selection menu |
| 96 | 296 | -------------------------------------------------*/ |
| r242899 | r242900 | |
| 226 | 426 | } |
| 227 | 427 | } |
| 228 | 428 | |
| 429 | /*------------------------------------------------- | |
| 430 | menu_input_groups_populate - populate the | |
| 431 | input groups menu | |
| 432 | -------------------------------------------------*/ | |
| 229 | 433 | |
| 434 | ui_menu_input_groups::ui_menu_input_groups(running_machine &machine, render_container *container) : ui_menu(machine, container) | |
| 435 | { | |
| 436 | } | |
| 437 | ||
| 438 | void ui_menu_input_groups::populate() | |
| 439 | { | |
| 440 | int player; | |
| 441 | ||
| 442 | /* build up the menu */ | |
| 443 | item_append("User Interface", NULL, 0, (void *)(IPG_UI + 1)); | |
| 444 | for (player = 0; player < MAX_PLAYERS; player++) | |
| 445 | { | |
| 446 | char buffer[40]; | |
| 447 | sprintf(buffer, "Player %d Controls", player + 1); | |
| 448 | item_append(buffer, NULL, 0, (void *)(FPTR)(IPG_PLAYER1 + player + 1)); | |
| 449 | } | |
| 450 | item_append("Other Controls", NULL, 0, (void *)(FPTR)(IPG_OTHER + 1)); | |
| 451 | } | |
| 452 | ||
| 453 | ui_menu_input_groups::~ui_menu_input_groups() | |
| 454 | { | |
| 455 | } | |
| 456 | ||
| 230 | 457 | /*------------------------------------------------- |
| 458 | menu_input_groups - handle the input groups | |
| 459 | menu | |
| 460 | -------------------------------------------------*/ | |
| 461 | ||
| 462 | void ui_menu_input_groups::handle() | |
| 463 | { | |
| 464 | /* process the menu */ | |
| 465 | const ui_menu_event *menu_event = process(0); | |
| 466 | if (menu_event != NULL && menu_event->iptkey == IPT_UI_SELECT) | |
| 467 | ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_input_general(machine(), container, int((long long)(menu_event->itemref)-1)))); | |
| 468 | } | |
| 469 | ||
| 470 | ||
| 471 | ||
| 472 | /*------------------------------------------------- | |
| 473 | menu_input_general - handle the general | |
| 474 | input menu | |
| 475 | -------------------------------------------------*/ | |
| 476 | ||
| 477 | ui_menu_input_general::ui_menu_input_general(running_machine &machine, render_container *container, int _group) : ui_menu_input(machine, container) | |
| 478 | { | |
| 479 | group = _group; | |
| 480 | } | |
| 481 | ||
| 482 | void ui_menu_input_general::populate() | |
| 483 | { | |
| 484 | input_item_data *itemlist = NULL; | |
| 485 | int suborder[SEQ_TYPE_TOTAL]; | |
| 486 | astring tempstring; | |
| 487 | int sortorder = 1; | |
| 488 | ||
| 489 | /* create a mini lookup table for sort order based on sequence type */ | |
| 490 | suborder[SEQ_TYPE_STANDARD] = 0; | |
| 491 | suborder[SEQ_TYPE_DECREMENT] = 1; | |
| 492 | suborder[SEQ_TYPE_INCREMENT] = 2; | |
| 493 | ||
| 494 | /* iterate over the input ports and add menu items */ | |
| 495 | for (input_type_entry *entry = machine().ioport().first_type(); entry != NULL; entry = entry->next()) | |
| 496 | ||
| 497 | /* add if we match the group and we have a valid name */ | |
| 498 | if (entry->group() == group && entry->name() != NULL && entry->name()[0] != 0) | |
| 499 | { | |
| 500 | input_seq_type seqtype; | |
| 501 | ||
| 502 | /* loop over all sequence types */ | |
| 503 | sortorder++; | |
| 504 | for (seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; seqtype++) | |
| 505 | { | |
| 506 | /* build an entry for the standard sequence */ | |
| 507 | input_item_data *item = (input_item_data *)m_pool_alloc(sizeof(*item)); | |
| 508 | memset(item, 0, sizeof(*item)); | |
| 509 | item->ref = entry; | |
| 510 | if(pollingitem && pollingref == entry && pollingseq == seqtype) | |
| 511 | pollingitem = item; | |
| 512 | item->seqtype = seqtype; | |
| 513 | item->seq = machine().ioport().type_seq(entry->type(), entry->player(), seqtype); | |
| 514 | item->defseq = &entry->defseq(seqtype); | |
| 515 | item->sortorder = sortorder * 4 + suborder[seqtype]; | |
| 516 | item->type = ioport_manager::type_is_analog(entry->type()) ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; | |
| 517 | item->name = entry->name(); | |
| 518 | item->owner_name = NULL; | |
| 519 | item->next = itemlist; | |
| 520 | itemlist = item; | |
| 521 | ||
| 522 | /* stop after one, unless we're analog */ | |
| 523 | if (item->type == INPUT_TYPE_DIGITAL) | |
| 524 | break; | |
| 525 | } | |
| 526 | } | |
| 527 | ||
| 528 | /* sort and populate the menu in a standard fashion */ | |
| 529 | populate_and_sort(itemlist); | |
| 530 | } | |
| 531 | ||
| 532 | ui_menu_input_general::~ui_menu_input_general() | |
| 533 | { | |
| 534 | } | |
| 535 | ||
| 536 | /*------------------------------------------------- | |
| 537 | menu_input_specific - handle the game-specific | |
| 538 | input menu | |
| 539 | -------------------------------------------------*/ | |
| 540 | ||
| 541 | ui_menu_input_specific::ui_menu_input_specific(running_machine &machine, render_container *container) : ui_menu_input(machine, container) | |
| 542 | { | |
| 543 | } | |
| 544 | ||
| 545 | void ui_menu_input_specific::populate() | |
| 546 | { | |
| 547 | input_item_data *itemlist = NULL; | |
| 548 | ioport_field *field; | |
| 549 | ioport_port *port; | |
| 550 | int suborder[SEQ_TYPE_TOTAL]; | |
| 551 | astring tempstring; | |
| 552 | ||
| 553 | /* create a mini lookup table for sort order based on sequence type */ | |
| 554 | suborder[SEQ_TYPE_STANDARD] = 0; | |
| 555 | suborder[SEQ_TYPE_DECREMENT] = 1; | |
| 556 | suborder[SEQ_TYPE_INCREMENT] = 2; | |
| 557 | ||
| 558 | /* iterate over the input ports and add menu items */ | |
| 559 | for (port = machine().ioport().first_port(); port != NULL; port = port->next()) | |
| 560 | for (field = port->first_field(); field != NULL; field = field->next()) | |
| 561 | { | |
| 562 | const char *name = field->name(); | |
| 563 | ||
| 564 | /* add if we match the group and we have a valid name */ | |
| 565 | if (name != NULL && field->enabled() && | |
| 566 | ((field->type() == IPT_OTHER && field->name() != NULL) || machine().ioport().type_group(field->type(), field->player()) != IPG_INVALID)) | |
| 567 | { | |
| 568 | input_seq_type seqtype; | |
| 569 | UINT32 sortorder; | |
| 570 | ||
| 571 | /* determine the sorting order */ | |
| 572 | if (field->type() >= IPT_START1 && field->type() < IPT_ANALOG_LAST) | |
| 573 | { | |
| 574 | sortorder = (field->type() << 2) | (field->player() << 12); | |
| 575 | if (strcmp(field->device().tag(), ":")) | |
| 576 | sortorder |= 0x10000; | |
| 577 | } | |
| 578 | else | |
| 579 | sortorder = field->type() | 0xf000; | |
| 580 | ||
| 581 | /* loop over all sequence types */ | |
| 582 | for (seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; seqtype++) | |
| 583 | { | |
| 584 | /* build an entry for the standard sequence */ | |
| 585 | input_item_data *item = (input_item_data *)m_pool_alloc(sizeof(*item)); | |
| 586 | memset(item, 0, sizeof(*item)); | |
| 587 | item->ref = field; | |
| 588 | item->seqtype = seqtype; | |
| 589 | if(pollingitem && pollingref == field && pollingseq == seqtype) | |
| 590 | pollingitem = item; | |
| 591 | item->seq = field->seq(seqtype); | |
| 592 | item->defseq = &field->defseq(seqtype); | |
| 593 | item->sortorder = sortorder + suborder[seqtype]; | |
| 594 | item->type = field->is_analog() ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; | |
| 595 | item->name = name; | |
| 596 | item->owner_name = field->device().tag(); | |
| 597 | item->next = itemlist; | |
| 598 | itemlist = item; | |
| 599 | ||
| 600 | /* stop after one, unless we're analog */ | |
| 601 | if (item->type == INPUT_TYPE_DIGITAL) | |
| 602 | break; | |
| 603 | } | |
| 604 | } | |
| 605 | } | |
| 606 | ||
| 607 | /* sort and populate the menu in a standard fashion */ | |
| 608 | populate_and_sort(itemlist); | |
| 609 | } | |
| 610 | ||
| 611 | ui_menu_input_specific::~ui_menu_input_specific() | |
| 612 | { | |
| 613 | } | |
| 614 | ||
| 615 | /*------------------------------------------------- | |
| 616 | menu_input - display a menu for inputs | |
| 617 | -------------------------------------------------*/ | |
| 618 | ui_menu_input::ui_menu_input(running_machine &machine, render_container *container) : ui_menu(machine, container) | |
| 619 | { | |
| 620 | pollingitem = 0; | |
| 621 | pollingref = 0; | |
| 622 | pollingseq = SEQ_TYPE_STANDARD; | |
| 623 | } | |
| 624 | ||
| 625 | ui_menu_input::~ui_menu_input() | |
| 626 | { | |
| 627 | } | |
| 628 | ||
| 629 | /*------------------------------------------------- | |
| 630 | toggle_none_default - toggle between "NONE" | |
| 631 | and the default item | |
| 632 | -------------------------------------------------*/ | |
| 633 | ||
| 634 | void ui_menu_input::toggle_none_default(input_seq &selected_seq, input_seq &original_seq, const input_seq &selected_defseq) | |
| 635 | { | |
| 636 | /* if we used to be "none", toggle to the default value */ | |
| 637 | if (original_seq.length() == 0) | |
| 638 | selected_seq = selected_defseq; | |
| 639 | ||
| 640 | /* otherwise, toggle to "none" */ | |
| 641 | else | |
| 642 | selected_seq.reset(); | |
| 643 | } | |
| 644 | ||
| 645 | void ui_menu_input::handle() | |
| 646 | { | |
| 647 | input_item_data *seqchangeditem = NULL; | |
| 648 | const ui_menu_event *menu_event; | |
| 649 | int invalidate = false; | |
| 650 | ||
| 651 | /* process the menu */ | |
| 652 | menu_event = process((pollingitem != NULL) ? UI_MENU_PROCESS_NOKEYS : 0); | |
| 653 | ||
| 654 | /* if we are polling, handle as a special case */ | |
| 655 | if (pollingitem != NULL) | |
| 656 | { | |
| 657 | input_item_data *item = pollingitem; | |
| 658 | input_seq newseq; | |
| 659 | ||
| 660 | /* if UI_CANCEL is pressed, abort */ | |
| 661 | if (ui_input_pressed(machine(), IPT_UI_CANCEL)) | |
| 662 | { | |
| 663 | pollingitem = NULL; | |
| 664 | record_next = false; | |
| 665 | toggle_none_default(item->seq, starting_seq, *item->defseq); | |
| 666 | seqchangeditem = item; | |
| 667 | } | |
| 668 | ||
| 669 | /* poll again; if finished, update the sequence */ | |
| 670 | if (machine().input().seq_poll()) | |
| 671 | { | |
| 672 | pollingitem = NULL; | |
| 673 | record_next = true; | |
| 674 | item->seq = machine().input().seq_poll_final(); | |
| 675 | seqchangeditem = item; | |
| 676 | } | |
| 677 | } | |
| 678 | ||
| 679 | /* otherwise, handle the events */ | |
| 680 | else if (menu_event != NULL && menu_event->itemref != NULL) | |
| 681 | { | |
| 682 | input_item_data *item = (input_item_data *)menu_event->itemref; | |
| 683 | switch (menu_event->iptkey) | |
| 684 | { | |
| 685 | /* an item was selected: begin polling */ | |
| 686 | case IPT_UI_SELECT: | |
| 687 | pollingitem = item; | |
| 688 | last_sortorder = item->sortorder; | |
| 689 | starting_seq = item->seq; | |
| 690 | machine().input().seq_poll_start((item->type == INPUT_TYPE_ANALOG) ? ITEM_CLASS_ABSOLUTE : ITEM_CLASS_SWITCH, record_next ? &item->seq : NULL); | |
| 691 | invalidate = true; | |
| 692 | break; | |
| 693 | ||
| 694 | /* if the clear key was pressed, reset the selected item */ | |
| 695 | case IPT_UI_CLEAR: | |
| 696 | toggle_none_default(item->seq, item->seq, *item->defseq); | |
| 697 | record_next = false; | |
| 698 | seqchangeditem = item; | |
| 699 | break; | |
| 700 | } | |
| 701 | ||
| 702 | /* if the selection changed, reset the "record next" flag */ | |
| 703 | if (item->sortorder != last_sortorder) | |
| 704 | record_next = false; | |
| 705 | last_sortorder = item->sortorder; | |
| 706 | } | |
| 707 | ||
| 708 | /* if the sequence changed, update it */ | |
| 709 | if (seqchangeditem != NULL) | |
| 710 | { | |
| 711 | update_input(seqchangeditem); | |
| 712 | ||
| 713 | /* invalidate the menu to force an update */ | |
| 714 | invalidate = true; | |
| 715 | } | |
| 716 | ||
| 717 | /* if the menu is invalidated, clear it now */ | |
| 718 | if (invalidate) | |
| 719 | { | |
| 720 | pollingref = NULL; | |
| 721 | if (pollingitem != NULL) | |
| 722 | { | |
| 723 | pollingref = pollingitem->ref; | |
| 724 | pollingseq = pollingitem->seqtype; | |
| 725 | } | |
| 726 | reset(UI_MENU_RESET_REMEMBER_POSITION); | |
| 727 | } | |
| 728 | } | |
| 729 | ||
| 730 | void ui_menu_input_general::update_input(struct input_item_data *seqchangeditem) | |
| 731 | { | |
| 732 | const input_type_entry *entry = (const input_type_entry *)seqchangeditem->ref; | |
| 733 | machine().ioport().set_type_seq(entry->type(), entry->player(), seqchangeditem->seqtype, seqchangeditem->seq); | |
| 734 | } | |
| 735 | ||
| 736 | void ui_menu_input_specific::update_input(struct input_item_data *seqchangeditem) | |
| 737 | { | |
| 738 | ioport_field::user_settings settings; | |
| 739 | ||
| 740 | ((ioport_field *)seqchangeditem->ref)->get_user_settings(settings); | |
| 741 | settings.seq[seqchangeditem->seqtype] = seqchangeditem->seq; | |
| 742 | ((ioport_field *)seqchangeditem->ref)->set_user_settings(settings); | |
| 743 | } | |
| 744 | ||
| 745 | ||
| 746 | /*------------------------------------------------- | |
| 747 | menu_input_compare_items - compare two | |
| 748 | items for quicksort | |
| 749 | -------------------------------------------------*/ | |
| 750 | ||
| 751 | int ui_menu_input::compare_items(const void *i1, const void *i2) | |
| 752 | { | |
| 753 | const input_item_data * const *data1 = (const input_item_data * const *)i1; | |
| 754 | const input_item_data * const *data2 = (const input_item_data * const *)i2; | |
| 755 | if ((*data1)->sortorder < (*data2)->sortorder) | |
| 756 | return -1; | |
| 757 | if ((*data1)->sortorder > (*data2)->sortorder) | |
| 758 | return 1; | |
| 759 | return 0; | |
| 760 | } | |
| 761 | ||
| 762 | ||
| 763 | /*------------------------------------------------- | |
| 764 | menu_input_populate_and_sort - take a list | |
| 765 | of input_item_data objects and build up the | |
| 766 | menu from them | |
| 767 | -------------------------------------------------*/ | |
| 768 | ||
| 769 | void ui_menu_input::populate_and_sort(input_item_data *itemlist) | |
| 770 | { | |
| 771 | const char *nameformat[INPUT_TYPE_TOTAL] = { 0 }; | |
| 772 | input_item_data **itemarray, *item; | |
| 773 | int numitems = 0, curitem; | |
| 774 | astring text; | |
| 775 | astring subtext; | |
| 776 | astring prev_owner; | |
| 777 | bool first_entry = true; | |
| 778 | ||
| 779 | /* create a mini lookup table for name format based on type */ | |
| 780 | nameformat[INPUT_TYPE_DIGITAL] = "%s"; | |
| 781 | nameformat[INPUT_TYPE_ANALOG] = "%s Analog"; | |
| 782 | nameformat[INPUT_TYPE_ANALOG_INC] = "%s Analog Inc"; | |
| 783 | nameformat[INPUT_TYPE_ANALOG_DEC] = "%s Analog Dec"; | |
| 784 | ||
| 785 | /* first count the number of items */ | |
| 786 | for (item = itemlist; item != NULL; item = item->next) | |
| 787 | numitems++; | |
| 788 | ||
| 789 | /* now allocate an array of items and fill it up */ | |
| 790 | itemarray = (input_item_data **)m_pool_alloc(sizeof(*itemarray) * numitems); | |
| 791 | for (item = itemlist, curitem = 0; item != NULL; item = item->next) | |
| 792 | itemarray[curitem++] = item; | |
| 793 | ||
| 794 | /* sort it */ | |
| 795 | qsort(itemarray, numitems, sizeof(*itemarray), compare_items); | |
| 796 | ||
| 797 | /* build the menu */ | |
| 798 | for (curitem = 0; curitem < numitems; curitem++) | |
| 799 | { | |
| 800 | UINT32 flags = 0; | |
| 801 | ||
| 802 | /* generate the name of the item itself, based off the base name and the type */ | |
| 803 | item = itemarray[curitem]; | |
| 804 | assert(nameformat[item->type] != NULL); | |
| 805 | ||
| 806 | if (strcmp(item->owner_name, prev_owner.cstr()) != 0) | |
| 807 | { | |
| 808 | if (first_entry) | |
| 809 | first_entry = false; | |
| 810 | else | |
| 811 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 812 | text.printf("[root%s]", item->owner_name); | |
| 813 | item_append(text, NULL, 0, NULL); | |
| 814 | prev_owner.cpy(item->owner_name); | |
| 815 | } | |
| 816 | ||
| 817 | text.printf(nameformat[item->type], item->name); | |
| 818 | ||
| 819 | /* if we're polling this item, use some spaces with left/right arrows */ | |
| 820 | if (pollingref == item->ref) | |
| 821 | { | |
| 822 | subtext.cpy(" "); | |
| 823 | flags |= MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW; | |
| 824 | } | |
| 825 | ||
| 826 | /* otherwise, generate the sequence name and invert it if different from the default */ | |
| 827 | else | |
| 828 | { | |
| 829 | machine().input().seq_name(subtext, item->seq); | |
| 830 | flags |= (item->seq != *item->defseq) ? MENU_FLAG_INVERT : 0; | |
| 831 | } | |
| 832 | ||
| 833 | /* add the item */ | |
| 834 | item_append(text, subtext, flags, item); | |
| 835 | } | |
| 836 | } | |
| 837 | ||
| 838 | ||
| 839 | /*------------------------------------------------- | |
| 840 | menu_settings_dip_switches - handle the DIP | |
| 841 | switches menu | |
| 842 | -------------------------------------------------*/ | |
| 843 | ||
| 844 | ui_menu_settings_dip_switches::ui_menu_settings_dip_switches(running_machine &machine, render_container *container) : ui_menu_settings(machine, container, IPT_DIPSWITCH) | |
| 845 | { | |
| 846 | } | |
| 847 | ||
| 848 | ui_menu_settings_dip_switches::~ui_menu_settings_dip_switches() | |
| 849 | { | |
| 850 | } | |
| 851 | ||
| 852 | /*------------------------------------------------- | |
| 853 | menu_settings_driver_config - handle the | |
| 854 | driver config menu | |
| 855 | -------------------------------------------------*/ | |
| 856 | ||
| 857 | ui_menu_settings_driver_config::ui_menu_settings_driver_config(running_machine &machine, render_container *container) : ui_menu_settings(machine, container, IPT_CONFIG) | |
| 858 | { | |
| 859 | } | |
| 860 | ||
| 861 | ui_menu_settings_driver_config::~ui_menu_settings_driver_config() | |
| 862 | { | |
| 863 | } | |
| 864 | ||
| 865 | /*------------------------------------------------- | |
| 866 | menu_settings_common - handle one of the | |
| 867 | switches menus | |
| 868 | -------------------------------------------------*/ | |
| 869 | ||
| 870 | void ui_menu_settings::handle() | |
| 871 | { | |
| 872 | // process the menu | |
| 873 | const ui_menu_event *menu_event = process(0); | |
| 874 | ||
| 875 | // handle events | |
| 876 | if (menu_event != NULL && menu_event->itemref != NULL) | |
| 877 | { | |
| 878 | // reset | |
| 879 | if ((FPTR)menu_event->itemref == 1) | |
| 880 | { | |
| 881 | if (menu_event->iptkey == IPT_UI_SELECT) | |
| 882 | machine().schedule_hard_reset(); | |
| 883 | } | |
| 884 | // actual settings | |
| 885 | else | |
| 886 | { | |
| 887 | ioport_field *field = (ioport_field *)menu_event->itemref; | |
| 888 | ioport_field::user_settings settings; | |
| 889 | int changed = false; | |
| 890 | ||
| 891 | switch (menu_event->iptkey) | |
| 892 | { | |
| 893 | /* if selected, reset to default value */ | |
| 894 | case IPT_UI_SELECT: | |
| 895 | field->get_user_settings(settings); | |
| 896 | settings.value = field->defvalue(); | |
| 897 | field->set_user_settings(settings); | |
| 898 | changed = true; | |
| 899 | break; | |
| 900 | ||
| 901 | /* left goes to previous setting */ | |
| 902 | case IPT_UI_LEFT: | |
| 903 | field->select_previous_setting(); | |
| 904 | changed = true; | |
| 905 | break; | |
| 906 | ||
| 907 | /* right goes to next setting */ | |
| 908 | case IPT_UI_RIGHT: | |
| 909 | field->select_next_setting(); | |
| 910 | changed = true; | |
| 911 | break; | |
| 912 | } | |
| 913 | ||
| 914 | /* if anything changed, rebuild the menu, trying to stay on the same field */ | |
| 915 | if (changed) | |
| 916 | reset(UI_MENU_RESET_REMEMBER_REF); | |
| 917 | } | |
| 918 | } | |
| 919 | } | |
| 920 | ||
| 921 | ||
| 922 | /*------------------------------------------------- | |
| 923 | menu_settings_populate - populate one of the | |
| 924 | switches menus | |
| 925 | -------------------------------------------------*/ | |
| 926 | ||
| 927 | ui_menu_settings::ui_menu_settings(running_machine &machine, render_container *container, UINT32 _type) : ui_menu(machine, container) | |
| 928 | { | |
| 929 | type = _type; | |
| 930 | } | |
| 931 | ||
| 932 | void ui_menu_settings::populate() | |
| 933 | { | |
| 934 | ioport_field *field; | |
| 935 | ioport_port *port; | |
| 936 | dip_descriptor **diplist_tailptr; | |
| 937 | astring prev_owner; | |
| 938 | bool first_entry = true; | |
| 939 | ||
| 940 | /* reset the dip switch tracking */ | |
| 941 | dipcount = 0; | |
| 942 | diplist = NULL; | |
| 943 | diplist_tailptr = &diplist; | |
| 944 | ||
| 945 | /* loop over input ports and set up the current values */ | |
| 946 | for (port = machine().ioport().first_port(); port != NULL; port = port->next()) | |
| 947 | for (field = port->first_field(); field != NULL; field = field->next()) | |
| 948 | if (field->type() == type && field->enabled()) | |
| 949 | { | |
| 950 | UINT32 flags = 0; | |
| 951 | astring name; | |
| 952 | ||
| 953 | /* set the left/right flags appropriately */ | |
| 954 | if (field->has_previous_setting()) | |
| 955 | flags |= MENU_FLAG_LEFT_ARROW; | |
| 956 | if (field->has_next_setting()) | |
| 957 | flags |= MENU_FLAG_RIGHT_ARROW; | |
| 958 | ||
| 959 | /* add the menu item */ | |
| 960 | if (strcmp(field->device().tag(), prev_owner.cstr()) != 0) | |
| 961 | { | |
| 962 | if (first_entry) | |
| 963 | first_entry = false; | |
| 964 | else | |
| 965 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 966 | name.printf("[root%s]", field->device().tag()); | |
| 967 | item_append(name, NULL, 0, NULL); | |
| 968 | prev_owner.cpy(field->device().tag()); | |
| 969 | } | |
| 970 | ||
| 971 | name.cpy(field->name()); | |
| 972 | ||
| 973 | item_append(name, field->setting_name(), flags, (void *)field); | |
| 974 | ||
| 975 | /* for DIP switches, build up the model */ | |
| 976 | if (type == IPT_DIPSWITCH && field->first_diplocation() != NULL) | |
| 977 | { | |
| 978 | const ioport_diplocation *diploc; | |
| 979 | ioport_field::user_settings settings; | |
| 980 | UINT32 accummask = field->mask(); | |
| 981 | ||
| 982 | /* get current settings */ | |
| 983 | field->get_user_settings(settings); | |
| 984 | ||
| 985 | /* iterate over each bit in the field */ | |
| 986 | for (diploc = field->first_diplocation(); diploc != NULL; diploc = diploc->next()) | |
| 987 | { | |
| 988 | UINT32 mask = accummask & ~(accummask - 1); | |
| 989 | dip_descriptor *dip; | |
| 990 | ||
| 991 | /* find the matching switch name */ | |
| 992 | for (dip = diplist; dip != NULL; dip = dip->next) | |
| 993 | if (strcmp(dip->name, diploc->name()) == 0) | |
| 994 | break; | |
| 995 | ||
| 996 | /* allocate new if none */ | |
| 997 | if (dip == NULL) | |
| 998 | { | |
| 999 | dip = (dip_descriptor *)m_pool_alloc(sizeof(*dip)); | |
| 1000 | dip->next = NULL; | |
| 1001 | dip->name = diploc->name(); | |
| 1002 | dip->mask = dip->state = 0; | |
| 1003 | *diplist_tailptr = dip; | |
| 1004 | diplist_tailptr = &dip->next; | |
| 1005 | dipcount++; | |
| 1006 | } | |
| 1007 | ||
| 1008 | /* apply the bits */ | |
| 1009 | dip->mask |= 1 << (diploc->number() - 1); | |
| 1010 | if (((settings.value & mask) != 0 && !diploc->inverted()) || ((settings.value & mask) == 0 && diploc->inverted())) | |
| 1011 | dip->state |= 1 << (diploc->number() - 1); | |
| 1012 | ||
| 1013 | /* clear the relevant bit in the accumulated mask */ | |
| 1014 | accummask &= ~mask; | |
| 1015 | } | |
| 1016 | } | |
| 1017 | } | |
| 1018 | if (type == IPT_DIPSWITCH) | |
| 1019 | custombottom = dipcount ? dipcount * (DIP_SWITCH_HEIGHT + DIP_SWITCH_SPACING) + DIP_SWITCH_SPACING : 0; | |
| 1020 | ||
| 1021 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 1022 | item_append("Reset", NULL, 0, (void *)1); | |
| 1023 | } | |
| 1024 | ||
| 1025 | ui_menu_settings::~ui_menu_settings() | |
| 1026 | { | |
| 1027 | } | |
| 1028 | ||
| 1029 | /*------------------------------------------------- | |
| 1030 | menu_settings_custom_render - perform our special | |
| 1031 | rendering | |
| 1032 | -------------------------------------------------*/ | |
| 1033 | ||
| 1034 | void ui_menu_settings_dip_switches::custom_render(void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2) | |
| 1035 | { | |
| 1036 | // catch if no diploc has to be drawn | |
| 1037 | if (bottom == 0) | |
| 1038 | return; | |
| 1039 | ||
| 1040 | // add borders | |
| 1041 | y1 = y2 + UI_BOX_TB_BORDER; | |
| 1042 | y2 = y1 + bottom; | |
| 1043 | ||
| 1044 | // draw extra menu area | |
| 1045 | machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR); | |
| 1046 | y1 += (float)DIP_SWITCH_SPACING; | |
| 1047 | ||
| 1048 | // iterate over DIP switches | |
| 1049 | for (dip_descriptor *dip = diplist; dip != NULL; dip = dip->next) | |
| 1050 | { | |
| 1051 | const ioport_diplocation *diploc; | |
| 1052 | UINT32 selectedmask = 0; | |
| 1053 | ||
| 1054 | // determine the mask of selected bits | |
| 1055 | if ((FPTR)selectedref != 1) | |
| 1056 | { | |
| 1057 | ioport_field *field = (ioport_field *)selectedref; | |
| 1058 | ||
| 1059 | if (field != NULL && field->first_diplocation() != NULL) | |
| 1060 | for (diploc = field->first_diplocation(); diploc != NULL; diploc = diploc->next()) | |
| 1061 | if (strcmp(dip->name, diploc->name()) == 0) | |
| 1062 | selectedmask |= 1 << (diploc->number() - 1); | |
| 1063 | } | |
| 1064 | ||
| 1065 | // draw one switch | |
| 1066 | custom_render_one(x1, y1, x2, y1 + DIP_SWITCH_HEIGHT, dip, selectedmask); | |
| 1067 | y1 += (float)(DIP_SWITCH_SPACING + DIP_SWITCH_HEIGHT); | |
| 1068 | } | |
| 1069 | } | |
| 1070 | ||
| 1071 | ||
| 1072 | /*------------------------------------------------- | |
| 1073 | menu_settings_custom_render_one - draw a single | |
| 1074 | DIP switch | |
| 1075 | -------------------------------------------------*/ | |
| 1076 | ||
| 1077 | void ui_menu_settings_dip_switches::custom_render_one(float x1, float y1, float x2, float y2, const dip_descriptor *dip, UINT32 selectedmask) | |
| 1078 | { | |
| 1079 | float switch_field_width = SINGLE_TOGGLE_SWITCH_FIELD_WIDTH * container->manager().ui_aspect(); | |
| 1080 | float switch_width = SINGLE_TOGGLE_SWITCH_WIDTH * container->manager().ui_aspect(); | |
| 1081 | int numtoggles, toggle; | |
| 1082 | float switch_toggle_gap; | |
| 1083 | float y1_off, y1_on; | |
| 1084 | ||
| 1085 | /* determine the number of toggles in the DIP */ | |
| 1086 | numtoggles = 32 - count_leading_zeros(dip->mask); | |
| 1087 | ||
| 1088 | /* center based on the number of switches */ | |
| 1089 | x1 += (x2 - x1 - numtoggles * switch_field_width) / 2; | |
| 1090 | ||
| 1091 | /* draw the dip switch name */ | |
| 1092 | machine().ui().draw_text_full( container, | |
| 1093 | dip->name, | |
| 1094 | 0, | |
| 1095 | y1 + (DIP_SWITCH_HEIGHT - UI_TARGET_FONT_HEIGHT) / 2, | |
| 1096 | x1 - machine().ui().get_string_width(" "), | |
| 1097 | JUSTIFY_RIGHT, | |
| 1098 | WRAP_NEVER, | |
| 1099 | DRAW_NORMAL, | |
| 1100 | UI_TEXT_COLOR, | |
| 1101 | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA), | |
| 1102 | NULL , | |
| 1103 | NULL); | |
| 1104 | ||
| 1105 | /* compute top and bottom for on and off positions */ | |
| 1106 | switch_toggle_gap = ((DIP_SWITCH_HEIGHT/2) - SINGLE_TOGGLE_SWITCH_HEIGHT)/2; | |
| 1107 | y1_off = y1 + UI_LINE_WIDTH + switch_toggle_gap; | |
| 1108 | y1_on = y1 + DIP_SWITCH_HEIGHT/2 + switch_toggle_gap; | |
| 1109 | ||
| 1110 | /* iterate over toggles */ | |
| 1111 | for (toggle = 0; toggle < numtoggles; toggle++) | |
| 1112 | { | |
| 1113 | float innerx1; | |
| 1114 | ||
| 1115 | /* first outline the switch */ | |
| 1116 | machine().ui().draw_outlined_box(container, x1, y1, x1 + switch_field_width, y2, UI_BACKGROUND_COLOR); | |
| 1117 | ||
| 1118 | /* compute x1/x2 for the inner filled in switch */ | |
| 1119 | innerx1 = x1 + (switch_field_width - switch_width) / 2; | |
| 1120 | ||
| 1121 | /* see if the switch is actually used */ | |
| 1122 | if (dip->mask & (1 << toggle)) | |
| 1123 | { | |
| 1124 | float innery1 = (dip->state & (1 << toggle)) ? y1_on : y1_off; | |
| 1125 | container->add_rect(innerx1, innery1, innerx1 + switch_width, innery1 + SINGLE_TOGGLE_SWITCH_HEIGHT, | |
| 1126 | (selectedmask & (1 << toggle)) ? UI_DIPSW_COLOR : UI_TEXT_COLOR, | |
| 1127 | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); | |
| 1128 | } | |
| 1129 | else | |
| 1130 | { | |
| 1131 | container->add_rect(innerx1, y1_off, innerx1 + switch_width, y1_on + SINGLE_TOGGLE_SWITCH_HEIGHT, | |
| 1132 | UI_UNAVAILABLE_COLOR, | |
| 1133 | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); | |
| 1134 | } | |
| 1135 | ||
| 1136 | /* advance to the next switch */ | |
| 1137 | x1 += switch_field_width; | |
| 1138 | } | |
| 1139 | } | |
| 1140 | ||
| 1141 | ||
| 1142 | /*------------------------------------------------- | |
| 1143 | menu_analog - handle the analog settings menu | |
| 1144 | -------------------------------------------------*/ | |
| 1145 | ||
| 1146 | void ui_menu_analog::handle() | |
| 1147 | { | |
| 1148 | /* process the menu */ | |
| 1149 | const ui_menu_event *menu_event = process(UI_MENU_PROCESS_LR_REPEAT); | |
| 1150 | ||
| 1151 | /* handle events */ | |
| 1152 | if (menu_event != NULL && menu_event->itemref != NULL) | |
| 1153 | { | |
| 1154 | analog_item_data *data = (analog_item_data *)menu_event->itemref; | |
| 1155 | int newval = data->cur; | |
| 1156 | ||
| 1157 | switch (menu_event->iptkey) | |
| 1158 | { | |
| 1159 | /* if selected, reset to default value */ | |
| 1160 | case IPT_UI_SELECT: | |
| 1161 | newval = data->defvalue; | |
| 1162 | break; | |
| 1163 | ||
| 1164 | /* left decrements */ | |
| 1165 | case IPT_UI_LEFT: | |
| 1166 | newval -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; | |
| 1167 | break; | |
| 1168 | ||
| 1169 | /* right increments */ | |
| 1170 | case IPT_UI_RIGHT: | |
| 1171 | newval += machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; | |
| 1172 | break; | |
| 1173 | } | |
| 1174 | ||
| 1175 | /* clamp to range */ | |
| 1176 | if (newval < data->min) | |
| 1177 | newval = data->min; | |
| 1178 | if (newval > data->max) | |
| 1179 | newval = data->max; | |
| 1180 | ||
| 1181 | /* if things changed, update */ | |
| 1182 | if (newval != data->cur) | |
| 1183 | { | |
| 1184 | ioport_field::user_settings settings; | |
| 1185 | ||
| 1186 | /* get the settings and set the new value */ | |
| 1187 | data->field->get_user_settings(settings); | |
| 1188 | switch (data->type) | |
| 1189 | { | |
| 1190 | case ANALOG_ITEM_KEYSPEED: settings.delta = newval; break; | |
| 1191 | case ANALOG_ITEM_CENTERSPEED: settings.centerdelta = newval; break; | |
| 1192 | case ANALOG_ITEM_REVERSE: settings.reverse = newval; break; | |
| 1193 | case ANALOG_ITEM_SENSITIVITY: settings.sensitivity = newval; break; | |
| 1194 | } | |
| 1195 | data->field->set_user_settings(settings); | |
| 1196 | ||
| 1197 | /* rebuild the menu */ | |
| 1198 | reset(UI_MENU_RESET_REMEMBER_POSITION); | |
| 1199 | } | |
| 1200 | } | |
| 1201 | } | |
| 1202 | ||
| 1203 | ||
| 1204 | /*------------------------------------------------- | |
| 1205 | menu_analog_populate - populate the analog | |
| 1206 | settings menu | |
| 1207 | -------------------------------------------------*/ | |
| 1208 | ||
| 1209 | ui_menu_analog::ui_menu_analog(running_machine &machine, render_container *container) : ui_menu(machine, container) | |
| 1210 | { | |
| 1211 | } | |
| 1212 | ||
| 1213 | void ui_menu_analog::populate() | |
| 1214 | { | |
| 1215 | ioport_field *field; | |
| 1216 | ioport_port *port; | |
| 1217 | astring text; | |
| 1218 | astring subtext; | |
| 1219 | astring prev_owner; | |
| 1220 | bool first_entry = true; | |
| 1221 | ||
| 1222 | /* loop over input ports and add the items */ | |
| 1223 | for (port = machine().ioport().first_port(); port != NULL; port = port->next()) | |
| 1224 | for (field = port->first_field(); field != NULL; field = field->next()) | |
| 1225 | if (field->is_analog() && field->enabled()) | |
| 1226 | { | |
| 1227 | ioport_field::user_settings settings; | |
| 1228 | int use_autocenter = false; | |
| 1229 | int type; | |
| 1230 | ||
| 1231 | /* based on the type, determine if we enable autocenter */ | |
| 1232 | switch (field->type()) | |
| 1233 | { | |
| 1234 | case IPT_POSITIONAL: | |
| 1235 | case IPT_POSITIONAL_V: | |
| 1236 | if (field->analog_wraps()) | |
| 1237 | break; | |
| 1238 | ||
| 1239 | case IPT_AD_STICK_X: | |
| 1240 | case IPT_AD_STICK_Y: | |
| 1241 | case IPT_AD_STICK_Z: | |
| 1242 | case IPT_PADDLE: | |
| 1243 | case IPT_PADDLE_V: | |
| 1244 | case IPT_PEDAL: | |
| 1245 | case IPT_PEDAL2: | |
| 1246 | case IPT_PEDAL3: | |
| 1247 | use_autocenter = true; | |
| 1248 | break; | |
| 1249 | ||
| 1250 | default: | |
| 1251 | break; | |
| 1252 | } | |
| 1253 | ||
| 1254 | /* get the user settings */ | |
| 1255 | field->get_user_settings(settings); | |
| 1256 | ||
| 1257 | /* iterate over types */ | |
| 1258 | for (type = 0; type < ANALOG_ITEM_COUNT; type++) | |
| 1259 | if (type != ANALOG_ITEM_CENTERSPEED || use_autocenter) | |
| 1260 | { | |
| 1261 | analog_item_data *data; | |
| 1262 | UINT32 flags = 0; | |
| 1263 | astring name; | |
| 1264 | if (strcmp(field->device().tag(), prev_owner.cstr()) != 0) | |
| 1265 | { | |
| 1266 | if (first_entry) | |
| 1267 | first_entry = false; | |
| 1268 | else | |
| 1269 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 1270 | name.printf("[root%s]", field->device().tag()); | |
| 1271 | item_append(name, NULL, 0, NULL); | |
| 1272 | prev_owner.cpy(field->device().tag()); | |
| 1273 | } | |
| 1274 | ||
| 1275 | name.cpy(field->name()); | |
| 1276 | ||
| 1277 | /* allocate a data item for tracking what this menu item refers to */ | |
| 1278 | data = (analog_item_data *)m_pool_alloc(sizeof(*data)); | |
| 1279 | data->field = field; | |
| 1280 | data->type = type; | |
| 1281 | ||
| 1282 | /* determine the properties of this item */ | |
| 1283 | switch (type) | |
| 1284 | { | |
| 1285 | default: | |
| 1286 | case ANALOG_ITEM_KEYSPEED: | |
| 1287 | text.printf("%s Digital Speed", name.cstr()); | |
| 1288 | subtext.printf("%d", settings.delta); | |
| 1289 | data->min = 0; | |
| 1290 | data->max = 255; | |
| 1291 | data->cur = settings.delta; | |
| 1292 | data->defvalue = field->delta(); | |
| 1293 | break; | |
| 1294 | ||
| 1295 | case ANALOG_ITEM_CENTERSPEED: | |
| 1296 | text.printf("%s Autocenter Speed", name.cstr()); | |
| 1297 | subtext.printf("%d", settings.centerdelta); | |
| 1298 | data->min = 0; | |
| 1299 | data->max = 255; | |
| 1300 | data->cur = settings.centerdelta; | |
| 1301 | data->defvalue = field->centerdelta(); | |
| 1302 | break; | |
| 1303 | ||
| 1304 | case ANALOG_ITEM_REVERSE: | |
| 1305 | text.printf("%s Reverse", name.cstr()); | |
| 1306 | subtext.cpy(settings.reverse ? "On" : "Off"); | |
| 1307 | data->min = 0; | |
| 1308 | data->max = 1; | |
| 1309 | data->cur = settings.reverse; | |
| 1310 | data->defvalue = field->analog_reverse(); | |
| 1311 | break; | |
| 1312 | ||
| 1313 | case ANALOG_ITEM_SENSITIVITY: | |
| 1314 | text.printf("%s Sensitivity", name.cstr()); | |
| 1315 | subtext.printf("%d", settings.sensitivity); | |
| 1316 | data->min = 1; | |
| 1317 | data->max = 255; | |
| 1318 | data->cur = settings.sensitivity; | |
| 1319 | data->defvalue = field->sensitivity(); | |
| 1320 | break; | |
| 1321 | } | |
| 1322 | ||
| 1323 | /* put on arrows */ | |
| 1324 | if (data->cur > data->min) | |
| 1325 | flags |= MENU_FLAG_LEFT_ARROW; | |
| 1326 | if (data->cur < data->max) | |
| 1327 | flags |= MENU_FLAG_RIGHT_ARROW; | |
| 1328 | ||
| 1329 | /* append a menu item */ | |
| 1330 | item_append(text, subtext, flags, data); | |
| 1331 | } | |
| 1332 | } | |
| 1333 | } | |
| 1334 | ||
| 1335 | ui_menu_analog::~ui_menu_analog() | |
| 1336 | { | |
| 1337 | } | |
| 1338 | ||
| 1339 | /*------------------------------------------------- | |
| 231 | 1340 | menu_bookkeeping - handle the bookkeeping |
| 232 | 1341 | information menu |
| 233 | 1342 | -------------------------------------------------*/ |
| r242899 | r242900 | |
|---|---|---|
| 25 | 25 | virtual void handle(); |
| 26 | 26 | }; |
| 27 | 27 | |
| 28 | class ui_menu_slot_devices : public ui_menu { | |
| 29 | public: | |
| 30 | ui_menu_slot_devices(running_machine &machine, render_container *container); | |
| 31 | virtual ~ui_menu_slot_devices(); | |
| 32 | virtual void populate(); | |
| 33 | virtual void handle(); | |
| 34 | ||
| 35 | private: | |
| 36 | device_slot_option *slot_get_current_option(device_slot_interface *slot); | |
| 37 | int slot_get_current_index(device_slot_interface *slot); | |
| 38 | int slot_get_length(device_slot_interface *slot); | |
| 39 | const char *slot_get_next(device_slot_interface *slot); | |
| 40 | const char *slot_get_prev(device_slot_interface *slot); | |
| 41 | const char *slot_get_option(device_slot_interface *slot, int index); | |
| 42 | void set_slot_device(device_slot_interface *slot, const char *val); | |
| 43 | }; | |
| 44 | ||
| 28 | 45 | class ui_menu_network_devices : public ui_menu { |
| 29 | 46 | public: |
| 30 | 47 | ui_menu_network_devices(running_machine &machine, render_container *container); |
| r242899 | r242900 | |
| 33 | 50 | virtual void handle(); |
| 34 | 51 | }; |
| 35 | 52 | |
| 53 | class ui_menu_input_groups : public ui_menu { | |
| 54 | public: | |
| 55 | ui_menu_input_groups(running_machine &machine, render_container *container); | |
| 56 | virtual ~ui_menu_input_groups(); | |
| 57 | virtual void populate(); | |
| 58 | virtual void handle(); | |
| 59 | }; | |
| 60 | ||
| 61 | class ui_menu_input : public ui_menu { | |
| 62 | public: | |
| 63 | ui_menu_input(running_machine &machine, render_container *container); | |
| 64 | virtual ~ui_menu_input(); | |
| 65 | virtual void handle(); | |
| 66 | ||
| 67 | protected: | |
| 68 | enum { | |
| 69 | INPUT_TYPE_DIGITAL = 0, | |
| 70 | INPUT_TYPE_ANALOG = 1, | |
| 71 | INPUT_TYPE_ANALOG_DEC = INPUT_TYPE_ANALOG + SEQ_TYPE_DECREMENT, | |
| 72 | INPUT_TYPE_ANALOG_INC = INPUT_TYPE_ANALOG + SEQ_TYPE_INCREMENT, | |
| 73 | INPUT_TYPE_TOTAL = INPUT_TYPE_ANALOG + SEQ_TYPE_TOTAL | |
| 74 | }; | |
| 75 | ||
| 76 | /* internal input menu item data */ | |
| 77 | struct input_item_data { | |
| 78 | input_item_data * next; /* pointer to next item in the list */ | |
| 79 | const void * ref; /* reference to type description for global inputs or field for game inputs */ | |
| 80 | input_seq_type seqtype; /* sequence type */ | |
| 81 | input_seq seq; /* copy of the live sequence */ | |
| 82 | const input_seq * defseq; /* pointer to the default sequence */ | |
| 83 | const char * name; /* pointer to the base name of the item */ | |
| 84 | const char * owner_name; /* pointer to the name of the owner of the item */ | |
| 85 | UINT32 sortorder; /* sorting information */ | |
| 86 | UINT8 type; /* type of port */ | |
| 87 | }; | |
| 88 | ||
| 89 | void populate_and_sort(struct input_item_data *itemlist); | |
| 90 | virtual void update_input(struct input_item_data *seqchangeditem) = 0; | |
| 91 | void toggle_none_default(input_seq &selected_seq, input_seq &original_seq, const input_seq &selected_defseq); | |
| 92 | ||
| 93 | protected: | |
| 94 | const void * pollingref; | |
| 95 | input_seq_type pollingseq; | |
| 96 | input_item_data * pollingitem; | |
| 97 | ||
| 98 | private: | |
| 99 | UINT16 last_sortorder; | |
| 100 | bool record_next; | |
| 101 | input_seq starting_seq; | |
| 102 | ||
| 103 | static int compare_items(const void *i1, const void *i2); | |
| 104 | }; | |
| 105 | ||
| 106 | class ui_menu_input_general : public ui_menu_input { | |
| 107 | public: | |
| 108 | ui_menu_input_general(running_machine &machine, render_container *container, int group); | |
| 109 | virtual ~ui_menu_input_general(); | |
| 110 | virtual void populate(); | |
| 111 | ||
| 112 | protected: | |
| 113 | int group; | |
| 114 | virtual void update_input(struct input_item_data *seqchangeditem); | |
| 115 | }; | |
| 116 | ||
| 117 | class ui_menu_input_specific : public ui_menu_input { | |
| 118 | public: | |
| 119 | ui_menu_input_specific(running_machine &machine, render_container *container); | |
| 120 | virtual ~ui_menu_input_specific(); | |
| 121 | virtual void populate(); | |
| 122 | ||
| 123 | protected: | |
| 124 | virtual void update_input(struct input_item_data *seqchangeditem); | |
| 125 | }; | |
| 126 | ||
| 127 | class ui_menu_settings : public ui_menu { | |
| 128 | public: | |
| 129 | ui_menu_settings(running_machine &machine, render_container *container, UINT32 type); | |
| 130 | virtual ~ui_menu_settings(); | |
| 131 | virtual void populate(); | |
| 132 | virtual void handle(); | |
| 133 | ||
| 134 | protected: | |
| 135 | /* DIP switch descriptor */ | |
| 136 | struct dip_descriptor { | |
| 137 | dip_descriptor * next; | |
| 138 | const char * name; | |
| 139 | UINT32 mask; | |
| 140 | UINT32 state; | |
| 141 | }; | |
| 142 | ||
| 143 | dip_descriptor * diplist; | |
| 144 | int dipcount; | |
| 145 | int type; | |
| 146 | }; | |
| 147 | ||
| 148 | class ui_menu_settings_dip_switches : public ui_menu_settings { | |
| 149 | public: | |
| 150 | ui_menu_settings_dip_switches(running_machine &machine, render_container *container); | |
| 151 | virtual ~ui_menu_settings_dip_switches(); | |
| 152 | ||
| 153 | virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2); | |
| 154 | private: | |
| 155 | void custom_render_one(float x1, float y1, float x2, float y2, const dip_descriptor *dip, UINT32 selectedmask); | |
| 156 | }; | |
| 157 | ||
| 158 | class ui_menu_settings_driver_config : public ui_menu_settings { | |
| 159 | public: | |
| 160 | ui_menu_settings_driver_config(running_machine &machine, render_container *container); | |
| 161 | virtual ~ui_menu_settings_driver_config(); | |
| 162 | }; | |
| 163 | ||
| 164 | class ui_menu_analog : public ui_menu { | |
| 165 | public: | |
| 166 | ui_menu_analog(running_machine &machine, render_container *container); | |
| 167 | virtual ~ui_menu_analog(); | |
| 168 | virtual void populate(); | |
| 169 | virtual void handle(); | |
| 170 | ||
| 171 | private: | |
| 172 | enum { | |
| 173 | ANALOG_ITEM_KEYSPEED = 0, | |
| 174 | ANALOG_ITEM_CENTERSPEED, | |
| 175 | ANALOG_ITEM_REVERSE, | |
| 176 | ANALOG_ITEM_SENSITIVITY, | |
| 177 | ANALOG_ITEM_COUNT | |
| 178 | }; | |
| 179 | ||
| 180 | /* internal analog menu item data */ | |
| 181 | struct analog_item_data { | |
| 182 | ioport_field *field; | |
| 183 | int type; | |
| 184 | int min, max; | |
| 185 | int cur; | |
| 186 | int defvalue; | |
| 187 | }; | |
| 188 | }; | |
| 189 | ||
| 36 | 190 | class ui_menu_bookkeeping : public ui_menu { |
| 37 | 191 | public: |
| 38 | 192 | ui_menu_bookkeeping(running_machine &machine, render_container *container); |
| r242899 | r242900 | |
|---|---|---|
| 17 | 17 | #include "cheat.h" |
| 18 | 18 | #include "uiinput.h" |
| 19 | 19 | #include "ui/selgame.h" |
| 20 | #include "ui/inputmap.h" | |
| 21 | 20 | #include "ui/miscmenu.h" |
| 22 | 21 | #include "audit.h" |
| 23 | 22 | #include "crsshair.h" |
| r242899 | r242900 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | ui/slotopt.c | |
| 4 | ||
| 5 | Internal menu for the slot options. | |
| 6 | ||
| 7 | Copyright Nicola Salmoria and the MAME Team. | |
| 8 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 9 | ||
| 10 | *********************************************************************/ | |
| 11 | ||
| 12 | #include "emu.h" | |
| 13 | ||
| 14 | #include "ui/ui.h" | |
| 15 | #include "ui/slotopt.h" | |
| 16 | ||
| 17 | ||
| 18 | /*------------------------------------------------- | |
| 19 | ui_slot_get_current_option - returns | |
| 20 | -------------------------------------------------*/ | |
| 21 | device_slot_option *ui_menu_slot_devices::slot_get_current_option(device_slot_interface *slot) | |
| 22 | { | |
| 23 | const char *current; | |
| 24 | if (slot->fixed()) | |
| 25 | { | |
| 26 | current = slot->default_option(); | |
| 27 | } | |
| 28 | else | |
| 29 | { | |
| 30 | astring temp; | |
| 31 | current = machine().options().main_value(temp, slot->device().tag() + 1); | |
| 32 | } | |
| 33 | ||
| 34 | return slot->option(current); | |
| 35 | } | |
| 36 | ||
| 37 | /*------------------------------------------------- | |
| 38 | ui_slot_get_current_index - returns | |
| 39 | -------------------------------------------------*/ | |
| 40 | int ui_menu_slot_devices::slot_get_current_index(device_slot_interface *slot) | |
| 41 | { | |
| 42 | const device_slot_option *current = slot_get_current_option(slot); | |
| 43 | ||
| 44 | if (current != NULL) | |
| 45 | { | |
| 46 | int val = 0; | |
| 47 | for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) | |
| 48 | { | |
| 49 | if (option == current) | |
| 50 | return val; | |
| 51 | ||
| 52 | if (option->selectable()) | |
| 53 | val++; | |
| 54 | } | |
| 55 | } | |
| 56 | ||
| 57 | return -1; | |
| 58 | } | |
| 59 | ||
| 60 | /*------------------------------------------------- | |
| 61 | ui_slot_get_length - returns | |
| 62 | -------------------------------------------------*/ | |
| 63 | int ui_menu_slot_devices::slot_get_length(device_slot_interface *slot) | |
| 64 | { | |
| 65 | int val = 0; | |
| 66 | for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) | |
| 67 | if (option->selectable()) | |
| 68 | val++; | |
| 69 | ||
| 70 | return val; | |
| 71 | } | |
| 72 | ||
| 73 | /*------------------------------------------------- | |
| 74 | ui_slot_get_next - returns | |
| 75 | -------------------------------------------------*/ | |
| 76 | const char *ui_menu_slot_devices::slot_get_next(device_slot_interface *slot) | |
| 77 | { | |
| 78 | int idx = slot_get_current_index(slot); | |
| 79 | if (idx < 0) | |
| 80 | idx = 0; | |
| 81 | else | |
| 82 | idx++; | |
| 83 | ||
| 84 | if (idx >= slot_get_length(slot)) | |
| 85 | return ""; | |
| 86 | ||
| 87 | return slot_get_option(slot, idx); | |
| 88 | } | |
| 89 | ||
| 90 | /*------------------------------------------------- | |
| 91 | ui_slot_get_prev - returns | |
| 92 | -------------------------------------------------*/ | |
| 93 | const char *ui_menu_slot_devices::slot_get_prev(device_slot_interface *slot) | |
| 94 | { | |
| 95 | int idx = slot_get_current_index(slot); | |
| 96 | if (idx < 0) | |
| 97 | idx = slot_get_length(slot) - 1; | |
| 98 | else | |
| 99 | idx--; | |
| 100 | ||
| 101 | if (idx < 0) | |
| 102 | return ""; | |
| 103 | ||
| 104 | return slot_get_option(slot, idx); | |
| 105 | } | |
| 106 | ||
| 107 | /*------------------------------------------------- | |
| 108 | ui_slot_get_option - returns | |
| 109 | -------------------------------------------------*/ | |
| 110 | const char *ui_menu_slot_devices::slot_get_option(device_slot_interface *slot, int index) | |
| 111 | { | |
| 112 | if (index >= 0) | |
| 113 | { | |
| 114 | int val = 0; | |
| 115 | for (const device_slot_option *option = slot->first_option(); option != NULL; option = option->next()) | |
| 116 | { | |
| 117 | if (val == index) | |
| 118 | return option->name(); | |
| 119 | ||
| 120 | if (option->selectable()) | |
| 121 | val++; | |
| 122 | } | |
| 123 | } | |
| 124 | ||
| 125 | return ""; | |
| 126 | } | |
| 127 | ||
| 128 | ||
| 129 | /*------------------------------------------------- | |
| 130 | ui_set_use_natural_keyboard - specifies | |
| 131 | whether the natural keyboard is active | |
| 132 | -------------------------------------------------*/ | |
| 133 | ||
| 134 | void ui_menu_slot_devices::set_slot_device(device_slot_interface *slot, const char *val) | |
| 135 | { | |
| 136 | astring error; | |
| 137 | machine().options().set_value(slot->device().tag()+1, val, OPTION_PRIORITY_CMDLINE, error); | |
| 138 | assert(!error); | |
| 139 | } | |
| 140 | ||
| 141 | /*------------------------------------------------- | |
| 142 | menu_slot_devices_populate - populates the main | |
| 143 | slot device menu | |
| 144 | -------------------------------------------------*/ | |
| 145 | ||
| 146 | ui_menu_slot_devices::ui_menu_slot_devices(running_machine &machine, render_container *container) : ui_menu(machine, container) | |
| 147 | { | |
| 148 | } | |
| 149 | ||
| 150 | void ui_menu_slot_devices::populate() | |
| 151 | { | |
| 152 | /* cycle through all devices for this system */ | |
| 153 | slot_interface_iterator iter(machine().root_device()); | |
| 154 | for (device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) | |
| 155 | { | |
| 156 | /* record the menu item */ | |
| 157 | const device_slot_option *option = slot_get_current_option(slot); | |
| 158 | astring opt_name; | |
| 159 | if (option == NULL) | |
| 160 | opt_name.cpy("------"); | |
| 161 | else | |
| 162 | { | |
| 163 | opt_name.cpy(option->name()); | |
| 164 | if (slot->fixed() || slot_get_length(slot) == 0) | |
| 165 | opt_name.cat(" [internal]"); | |
| 166 | } | |
| 167 | ||
| 168 | item_append(slot->device().tag() + 1, opt_name, (slot->fixed() || slot_get_length(slot) == 0) ? 0 : (MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW), (void *)slot); | |
| 169 | } | |
| 170 | item_append(MENU_SEPARATOR_ITEM, NULL, 0, NULL); | |
| 171 | item_append("Reset", NULL, 0, (void *)1); | |
| 172 | } | |
| 173 | ||
| 174 | ui_menu_slot_devices::~ui_menu_slot_devices() | |
| 175 | { | |
| 176 | } | |
| 177 | ||
| 178 | /*------------------------------------------------- | |
| 179 | ui_menu_slot_devices - menu that | |
| 180 | -------------------------------------------------*/ | |
| 181 | ||
| 182 | void ui_menu_slot_devices::handle() | |
| 183 | { | |
| 184 | /* process the menu */ | |
| 185 | const ui_menu_event *menu_event = process(0); | |
| 186 | ||
| 187 | if (menu_event != NULL && menu_event->itemref != NULL) | |
| 188 | { | |
| 189 | if ((FPTR)menu_event->itemref == 1 && menu_event->iptkey == IPT_UI_SELECT) | |
| 190 | machine().schedule_hard_reset(); | |
| 191 | else if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) | |
| 192 | { | |
| 193 | device_slot_interface *slot = (device_slot_interface *)menu_event->itemref; | |
| 194 | const char *val = (menu_event->iptkey == IPT_UI_LEFT) ? slot_get_prev(slot) : slot_get_next(slot); | |
| 195 | set_slot_device(slot, val); | |
| 196 | reset(UI_MENU_RESET_REMEMBER_REF); | |
| 197 | } | |
| 198 | } | |
| 199 | } |
| r242899 | r242900 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 2 | ||
| 3 | ui/slotopt.h | |
| 4 | ||
| 5 | Internal menu for the slot options. | |
| 6 | ||
| 7 | Copyright Nicola Salmoria and the MAME Team. | |
| 8 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 9 | ||
| 10 | ***************************************************************************/ | |
| 11 | ||
| 12 | #pragma once | |
| 13 | ||
| 14 | #ifndef __UI_SLOTOPT_H__ | |
| 15 | #define __UI_SLOTOPT_H__ | |
| 16 | ||
| 17 | //#include "drivenum.h" | |
| 18 | ||
| 19 | class ui_menu_slot_devices : public ui_menu { | |
| 20 | public: | |
| 21 | ui_menu_slot_devices(running_machine &machine, render_container *container); | |
| 22 | virtual ~ui_menu_slot_devices(); | |
| 23 | virtual void populate(); | |
| 24 | virtual void handle(); | |
| 25 | ||
| 26 | private: | |
| 27 | device_slot_option *slot_get_current_option(device_slot_interface *slot); | |
| 28 | int slot_get_current_index(device_slot_interface *slot); | |
| 29 | int slot_get_length(device_slot_interface *slot); | |
| 30 | const char *slot_get_next(device_slot_interface *slot); | |
| 31 | const char *slot_get_prev(device_slot_interface *slot); | |
| 32 | const char *slot_get_option(device_slot_interface *slot, int index); | |
| 33 | void set_slot_device(device_slot_interface *slot, const char *val); | |
| 34 | }; | |
| 35 | ||
| 36 | #endif /* __UI_SLOTOPT_H__ */ |
| r242899 | r242900 | |
|---|---|---|
| 525 | 525 | $(LIBOBJ)/lua/ltablib.o \ |
| 526 | 526 | $(LIBOBJ)/lua/loadlib.o \ |
| 527 | 527 | $(LIBOBJ)/lua/linit.o \ |
| 528 | $(LIBOBJ)/lua/lutf8lib.o \ | |
| 529 | 528 | $(LIBOBJ)/lua/lsqlite3/lsqlite3.o \ |
| 530 | 529 | |
| 531 | 530 | $(OBJ)/liblua.a: $(LUAOBJS) |
| r242899 | r242900 | |
|---|---|---|
| 526 | 526 | |
| 527 | 527 | |
| 528 | 528 | |
| 529 | void dec0_automat_state::machine_start() | |
| 530 | { | |
| 531 | save_item(NAME(m_automat_adpcm_byte)); | |
| 532 | save_item(NAME(m_automat_msm5205_vclk_toggle)); | |
| 533 | save_item(NAME(m_automat_scroll_regs)); | |
| 534 | } | |
| 535 | 529 | |
| 536 | 530 | |
| 531 | ||
| 537 | 532 | /* swizzle the palette writes around so we can use the same gfx plane ordering as the originals */ |
| 538 | 533 | READ16_MEMBER( dec0_automat_state::automat_palette_r ) |
| 539 | 534 | { |
| r242899 | r242900 | |
| 3039 | 3034 | return 0xffff; |
| 3040 | 3035 | } |
| 3041 | 3036 | |
| 3037 | READ16_MEMBER(dec0_state::ffantasybl_vblank_r) | |
| 3038 | { | |
| 3039 | return ioport("VBLANK")->read(); | |
| 3040 | } | |
| 3041 | ||
| 3042 | 3042 | DRIVER_INIT_MEMBER(dec0_state,ffantasybl) |
| 3043 | 3043 | { |
| 3044 | 3044 | m_maincpu->space(AS_PROGRAM).install_ram(0x24c880, 0x24cbff); // what is this? layer 3-related?? |
| 3045 | 3045 | |
| 3046 | 3046 | m_maincpu->space(AS_PROGRAM).install_read_handler(0x00242024, 0x00242025, read16_delegate(FUNC(dec0_state::ffantasybl_242024_r),this)); |
| 3047 | m_maincpu->space(AS_PROGRAM).install_read_ | |
| 3047 | m_maincpu->space(AS_PROGRAM).install_read_handler(0x00ff87ee, 0x00ff87ef, read16_delegate(FUNC(dec0_state::ffantasybl_vblank_r),this)); | |
| 3048 | 3048 | } |
| 3049 | 3049 | |
| 3050 | 3050 | /******************************************************************************/ |
| 3051 | 3051 | |
| 3052 | 3052 | // YEAR, NAME, PARENT, MACHINE, INPUT, STATE/DEVICE, INIT, MONITOR,COMPANY, FULLNAME, FLAGS |
| 3053 | GAME( 1987, hbarrel, 0, hbarrel, hbarrel, dec0_state, hbarrel, ROT270, "Data East USA", "Heavy Barrel (US)", GAME_SUPPORTS_SAVE ) | |
| 3054 | GAME( 1987, hbarrelw, hbarrel, hbarrel, hbarrel, dec0_state, hbarrel, ROT270, "Data East Corporation", "Heavy Barrel (World)", GAME_SUPPORTS_SAVE ) | |
| 3055 | GAME( 1988, baddudes, 0, baddudes, baddudes, dec0_state, baddudes, ROT0, "Data East USA", "Bad Dudes vs. Dragonninja (US)", GAME_SUPPORTS_SAVE ) | |
| 3056 | GAME( 1988, drgninja, baddudes, baddudes, drgninja, dec0_state, baddudes, ROT0, "Data East Corporation", "Dragonninja (Japan)", GAME_SUPPORTS_SAVE ) | |
| 3057 | GAME( 1988, birdtry, 0, birdtry, birdtry, dec0_state, birdtry, ROT270, "Data East Corporation", "Birdie Try (Japan)", GAME_UNEMULATED_PROTECTION | GAME_SUPPORTS_SAVE ) | |
| 3058 | GAME( 1988, robocop, 0, robocop, robocop, dec0_state, robocop, ROT0, "Data East Corporation", "Robocop (World revision 4)", GAME_SUPPORTS_SAVE ) | |
| 3059 | GAME( 1988, robocopw, robocop, robocop, robocop, dec0_state, robocop, ROT0, "Data East Corporation", "Robocop (World revision 3)", GAME_SUPPORTS_SAVE ) | |
| 3060 | GAME( 1988, robocopj, robocop, robocop, robocop, dec0_state, robocop, ROT0, "Data East Corporation", "Robocop (Japan)", GAME_SUPPORTS_SAVE ) | |
| 3061 | GAME( 1988, robocopu, robocop, robocop, robocop, dec0_state, robocop, ROT0, "Data East USA", "Robocop (US revision 1)", GAME_SUPPORTS_SAVE ) | |
| 3062 | GAME( 1988, robocopu0, robocop, robocop, robocop, dec0_state, robocop, ROT0, "Data East USA", "Robocop (US revision 0)", GAME_SUPPORTS_SAVE ) | |
| 3063 | GAME( 1989, hippodrm, 0, hippodrm, hippodrm, dec0_state, hippodrm, ROT0, "Data East USA", "Hippodrome (US)", GAME_SUPPORTS_SAVE ) | |
| 3064 | GAME( 1989, ffantasy, hippodrm, hippodrm, ffantasy, dec0_state, hippodrm, ROT0, "Data East Corporation", "Fighting Fantasy (Japan revision 2)", GAME_SUPPORTS_SAVE ) | |
| 3065 | GAME( 1989, ffantasya, hippodrm, hippodrm, ffantasy, dec0_state, hippodrm, ROT0, "Data East Corporation", "Fighting Fantasy (Japan)", GAME_SUPPORTS_SAVE ) | |
| 3066 | GAME( 1989, secretag, 0, slyspy, slyspy, dec0_state, slyspy, ROT0, "Data East Corporation", "Secret Agent (World revision 3)", GAME_SUPPORTS_SAVE ) | |
| 3067 | GAME( 1989, secretagj, secretag, slyspy, slyspy, dec0_state, slyspy, ROT0, "Data East Corporation", "Secret Agent (Japan revision 2)", GAME_SUPPORTS_SAVE ) | |
| 3068 | GAME( 1989, slyspy, secretag, slyspy, slyspy, dec0_state, slyspy, ROT0, "Data East USA", "Sly Spy (US revision 3)", GAME_SUPPORTS_SAVE ) | |
| 3069 | GAME( 1989, slyspy2, secretag, slyspy, slyspy, dec0_state, slyspy, ROT0, "Data East USA", "Sly Spy (US revision 2)", GAME_SUPPORTS_SAVE ) | |
| 3070 | GAME( 1989, midres, 0, midres, midres, driver_device, 0, ROT0, "Data East Corporation", "Midnight Resistance (World)", GAME_SUPPORTS_SAVE ) | |
| 3071 | GAME( 1989, midresu, midres, midres, midresu, driver_device, 0, ROT0, "Data East USA", "Midnight Resistance (US)", GAME_SUPPORTS_SAVE ) | |
| 3072 | GAME( 1989, midresj, midres, midres, midresu, driver_device, 0, ROT0, "Data East Corporation", "Midnight Resistance (Japan)", GAME_SUPPORTS_SAVE ) | |
| 3073 | GAME( 1990, bouldash, 0, slyspy, bouldash, dec0_state, slyspy, ROT0, "Data East Corporation (licensed from First Star)", "Boulder Dash / Boulder Dash Part 2 (World)", GAME_SUPPORTS_SAVE ) | |
| 3074 | GAME( 1990, bouldashj, bouldash, slyspy, bouldash, dec0_state, slyspy, ROT0, "Data East Corporation (licensed from First Star)", "Boulder Dash / Boulder Dash Part 2 (Japan)", GAME_SUPPORTS_SAVE ) | |
| 3053 | GAME( 1987, hbarrel, 0, hbarrel, hbarrel, dec0_state, hbarrel, ROT270, "Data East USA", "Heavy Barrel (US)", 0 ) | |
| 3054 | GAME( 1987, hbarrelw, hbarrel, hbarrel, hbarrel, dec0_state, hbarrel, ROT270, "Data East Corporation", "Heavy Barrel (World)", 0 ) | |
| 3055 | GAME( 1988, baddudes, 0, baddudes, baddudes, dec0_state, baddudes, ROT0, "Data East USA", "Bad Dudes vs. Dragonninja (US)", 0 ) | |
| 3056 | GAME( 1988, drgninja, baddudes, baddudes, drgninja, dec0_state, baddudes, ROT0, "Data East Corporation", "Dragonninja (Japan)", 0 ) | |
| 3057 | GAME( 1988, birdtry, 0, birdtry, birdtry, dec0_state, birdtry, ROT270, "Data East Corporation", "Birdie Try (Japan)", GAME_UNEMULATED_PROTECTION ) | |
| 3058 | GAME( 1988, robocop, 0, robocop, robocop, dec0_state, robocop, ROT0, "Data East Corporation", "Robocop (World revision 4)", 0 ) | |
| 3059 | GAME( 1988, robocopw, robocop, robocop, robocop, dec0_state, robocop, ROT0, "Data East Corporation", "Robocop (World revision 3)", 0 ) | |
| 3060 | GAME( 1988, robocopj, robocop, robocop, robocop, dec0_state, robocop, ROT0, "Data East Corporation", "Robocop (Japan)", 0 ) | |
| 3061 | GAME( 1988, robocopu, robocop, robocop, robocop, dec0_state, robocop, ROT0, "Data East USA", "Robocop (US revision 1)", 0 ) | |
| 3062 | GAME( 1988, robocopu0, robocop, robocop, robocop, dec0_state, robocop, ROT0, "Data East USA", "Robocop (US revision 0)", 0 ) | |
| 3063 | GAME( 1989, hippodrm, 0, hippodrm, hippodrm, dec0_state, hippodrm, ROT0, "Data East USA", "Hippodrome (US)", 0 ) | |
| 3064 | GAME( 1989, ffantasy, hippodrm, hippodrm, ffantasy, dec0_state, hippodrm, ROT0, "Data East Corporation", "Fighting Fantasy (Japan revision 2)", 0 ) | |
| 3065 | GAME( 1989, ffantasya, hippodrm, hippodrm, ffantasy, dec0_state, hippodrm, ROT0, "Data East Corporation", "Fighting Fantasy (Japan)", 0 ) | |
| 3066 | GAME( 1989, secretag, 0, slyspy, slyspy, dec0_state, slyspy, ROT0, "Data East Corporation", "Secret Agent (World revision 3)", 0 ) | |
| 3067 | GAME( 1989, secretagj, secretag, slyspy, slyspy, dec0_state, slyspy, ROT0, "Data East Corporation", "Secret Agent (Japan revision 2)", 0 ) | |
| 3068 | GAME( 1989, slyspy, secretag, slyspy, slyspy, dec0_state, slyspy, ROT0, "Data East USA", "Sly Spy (US revision 3)", 0 ) | |
| 3069 | GAME( 1989, slyspy2, secretag, slyspy, slyspy, dec0_state, slyspy, ROT0, "Data East USA", "Sly Spy (US revision 2)", 0 ) | |
| 3070 | GAME( 1989, midres, 0, midres, midres, driver_device, 0, ROT0, "Data East Corporation", "Midnight Resistance (World)", 0 ) | |
| 3071 | GAME( 1989, midresu, midres, midres, midresu, driver_device, 0, ROT0, "Data East USA", "Midnight Resistance (US)", 0 ) | |
| 3072 | GAME( 1989, midresj, midres, midres, midresu, driver_device, 0, ROT0, "Data East Corporation", "Midnight Resistance (Japan)", 0 ) | |
| 3073 | GAME( 1990, bouldash, 0, slyspy, bouldash, dec0_state, slyspy, ROT0, "Data East Corporation (licensed from First Star)", "Boulder Dash / Boulder Dash Part 2 (World)", 0 ) | |
| 3074 | GAME( 1990, bouldashj, bouldash, slyspy, bouldash, dec0_state, slyspy, ROT0, "Data East Corporation (licensed from First Star)", "Boulder Dash / Boulder Dash Part 2 (Japan)", 0 ) | |
| 3075 | 3075 | |
| 3076 | 3076 | // bootlegs |
| 3077 | 3077 | |
| 3078 | 3078 | // more or less just an unprotected versions of the game, everything intact |
| 3079 | GAME( 1988, robocopb, robocop, robocopb, robocop, dec0_state, robocop, ROT0, "bootleg", "Robocop (World bootleg)", GAME_SUPPORTS_SAVE ) | |
| 3080 | GAME( 1988, drgninjab, baddudes, baddudes, drgninja, dec0_state, baddudes, ROT0, "bootleg", "Dragonninja (bootleg)", GAME_SUPPORTS_SAVE ) | |
| 3079 | GAME( 1988, robocopb, robocop, robocopb, robocop, dec0_state, robocop, ROT0, "bootleg", "Robocop (World bootleg)", 0) | |
| 3080 | GAME( 1988, drgninjab, baddudes, baddudes, drgninja, dec0_state, baddudes, ROT0, "bootleg", "Dragonninja (bootleg)", 0 ) | |
| 3081 | 3081 | |
| 3082 | 3082 | // this is a common bootleg board |
| 3083 | GAME( 1989, midresb, midres, midresb, midresb, dec0_state, midresb, ROT0, "bootleg", "Midnight Resistance (bootleg with 68705)", GAME_SUPPORTS_SAVE ) // need to hook up 68705? | |
| 3084 | GAME( 1989, ffantasybl, hippodrm, ffantasybl, ffantasybl, dec0_state, ffantasybl, ROT0, "bootleg", "Fighting Fantasy (bootleg with 68705)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE ) // 68705 not dumped, might be the same as midresb | |
| 3083 | GAME( 1989, midresb, midres, midresb, midresb, dec0_state, midresb, ROT0, "bootleg", "Midnight Resistance (bootleg with 68705)", 0 ) // need to hook up 68705? | |
| 3084 | GAME( 1989, ffantasybl, hippodrm, ffantasybl, ffantasybl, dec0_state, ffantasybl, ROT0, "bootleg", "Fighting Fantasy (bootleg with 68705)", GAME_IMPERFECT_GRAPHICS ) // 68705 not dumped, might be the same as midresb | |
| 3085 | 3085 | /* A Bad Dudes bootleg with 68705 like the midres and ffantasy ones exists, but is not dumped */ |
| 3086 | 3086 | |
| 3087 | 3087 | // these are different to the above but quite similar to each other |
| 3088 | GAME( 1988, automat, robocop, automat, robocop, dec0_state, robocop, ROT0, "bootleg", "Automat (bootleg of Robocop)", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE ) // sound rom / music from section z with mods for ADPCM? | |
| 3089 | GAME( 1989, secretab, secretag, secretab, slyspy, dec0_state, slyspy, ROT0, "bootleg", "Secret Agent (bootleg)", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE ) | |
| 3088 | GAME( 1988, automat, robocop, automat, robocop, dec0_state, robocop, ROT0, "bootleg", "Automat (bootleg of Robocop)", GAME_NOT_WORKING ) // sound rom / music from section z with mods for ADPCM? | |
| 3089 | GAME( 1989, secretab, secretag, secretab, slyspy, dec0_state, slyspy, ROT0, "bootleg", "Secret Agent (bootleg)", GAME_NOT_WORKING ) |
| r242899 | r242900 | |
|---|---|---|
| 98 | 98 | case 4: m_gear[i] = 3; break; |
| 99 | 99 | case 8: m_gear[i] = 4; break; |
| 100 | 100 | } |
| 101 | output_set_value("P1gear", m_gear[0]); | |
| 102 | output_set_value("P2gear", m_gear[1]); | |
| 101 | 103 | } |
| 102 | 104 | } |
| 103 | 105 |
| r242899 | r242900 | |
|---|---|---|
| 8 | 8 | public: |
| 9 | 9 | dec0_state(const machine_config &mconfig, device_type type, const char *tag) |
| 10 | 10 | : driver_device(mconfig, type, tag), |
| 11 | m_maincpu(*this, "maincpu"), | |
| 12 | m_audiocpu(*this, "audiocpu"), | |
| 13 | m_subcpu(*this, "sub"), | |
| 14 | m_mcu(*this, "mcu"), | |
| 15 | m_msm(*this, "msm"), | |
| 16 | m_palette(*this, "palette"), | |
| 11 | m_ram(*this, "ram"), | |
| 12 | m_spriteram(*this, "spriteram"), | |
| 13 | m_paletteram(*this, "palette"), | |
| 14 | m_robocop_shared_ram(*this, "robocop_shared"), | |
| 15 | m_hippodrm_shared_ram(*this, "hippodrm_shared"), | |
| 17 | 16 | m_tilegen1(*this, "tilegen1"), |
| 18 | 17 | m_tilegen2(*this, "tilegen2"), |
| 19 | 18 | m_tilegen3(*this, "tilegen3"), |
| 20 | 19 | m_spritegen(*this, "spritegen"), |
| 21 | 20 | m_pfprotect(*this, "pfprotect"), |
| 22 | m_ram(*this, "ram"), | |
| 23 | m_spriteram(*this, "spriteram"), | |
| 24 | m_paletteram(*this, "palette"), | |
| 25 | m_robocop_shared_ram(*this, "robocop_shared"), | |
| 26 | m_hippodrm_shared_ram(*this, "hippodrm_shared") { } | |
| 27 | ||
| 28 | required_device<cpu_device> m_maincpu; | |
| 29 | required_device<cpu_device> m_audiocpu; | |
| 30 | optional_device<cpu_device> m_subcpu; | |
| 31 | optional_device<cpu_device> m_mcu; | |
| 32 | optional_device<msm5205_device> m_msm; | |
| 33 | required_device<palette_device> m_palette; | |
| 34 | optional_device<deco_bac06_device> m_tilegen1; | |
| 35 | optional_device<deco_bac06_device> m_tilegen2; | |
| 36 | optional_device<deco_bac06_device> m_tilegen3; | |
| 37 | optional_device<deco_mxc06_device> m_spritegen; | |
| 38 | optional_device<address_map_bank_device> m_pfprotect; | |
| 21 | m_maincpu(*this, "maincpu"), | |
| 22 | m_audiocpu(*this, "audiocpu"), | |
| 23 | m_subcpu(*this, "sub"), | |
| 24 | m_mcu(*this, "mcu"), | |
| 25 | m_msm(*this, "msm"), | |
| 26 | m_palette(*this, "palette") { } | |
| 39 | 27 | |
| 40 | 28 | required_shared_ptr<UINT16> m_ram; |
| 41 | 29 | required_shared_ptr<UINT16> m_spriteram; |
| r242899 | r242900 | |
| 43 | 31 | optional_shared_ptr<UINT8> m_robocop_shared_ram; |
| 44 | 32 | optional_shared_ptr<UINT8> m_hippodrm_shared_ram; |
| 45 | 33 | |
| 46 | int m_game; | |
| 34 | optional_device<deco_bac06_device> m_tilegen1; | |
| 35 | optional_device<deco_bac06_device> m_tilegen2; | |
| 36 | optional_device<deco_bac06_device> m_tilegen3; | |
| 37 | optional_device<deco_mxc06_device> m_spritegen; | |
| 38 | ||
| 39 | optional_device<address_map_bank_device> m_pfprotect; | |
| 40 | ||
| 41 | int m_GAME; | |
| 47 | 42 | int m_i8751_return; |
| 48 | 43 | int m_i8751_command; |
| 49 | 44 | int m_slyspy_state; |
| 50 | 45 | int m_hippodrm_msb; |
| 51 | 46 | int m_hippodrm_lsb; |
| 52 | 47 | UINT8 m_i8751_ports[4]; |
| 48 | ||
| 53 | 49 | UINT16 *m_buffered_spriteram; |
| 54 | 50 | UINT16 m_pri; |
| 55 | ||
| 56 | 51 | DECLARE_WRITE16_MEMBER(dec0_control_w); |
| 57 | 52 | DECLARE_WRITE16_MEMBER(slyspy_control_w); |
| 58 | 53 | DECLARE_WRITE16_MEMBER(midres_sound_w); |
| r242899 | r242900 | |
| 75 | 70 | DECLARE_WRITE16_MEMBER(dec0_update_sprites_w); |
| 76 | 71 | DECLARE_WRITE16_MEMBER(dec0_priority_w); |
| 77 | 72 | DECLARE_READ16_MEMBER(ffantasybl_242024_r); |
| 78 | DECLARE_WRITE_LINE_MEMBER(sound_irq); | |
| 79 | DECLARE_WRITE_LINE_MEMBER(sound_irq2); | |
| 80 | ||
| 73 | DECLARE_READ16_MEMBER(ffantasybl_vblank_r); | |
| 81 | 74 | DECLARE_DRIVER_INIT(robocop); |
| 82 | 75 | DECLARE_DRIVER_INIT(hippodrm); |
| 83 | 76 | DECLARE_DRIVER_INIT(hbarrel); |
| r242899 | r242900 | |
| 86 | 79 | DECLARE_DRIVER_INIT(baddudes); |
| 87 | 80 | DECLARE_DRIVER_INIT(midresb); |
| 88 | 81 | DECLARE_DRIVER_INIT(ffantasybl); |
| 89 | ||
| 90 | virtual void machine_start(); | |
| 91 | DECLARE_MACHINE_RESET(slyspy); | |
| 92 | 82 | DECLARE_VIDEO_START(dec0); |
| 83 | DECLARE_MACHINE_RESET(slyspy); | |
| 93 | 84 | DECLARE_VIDEO_START(dec0_nodma); |
| 94 | ||
| 95 | 85 | UINT32 screen_update_hbarrel(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 96 | 86 | UINT32 screen_update_baddudes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 97 | 87 | UINT32 screen_update_birdtry(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| r242899 | r242900 | |
| 99 | 89 | UINT32 screen_update_hippodrm(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 100 | 90 | UINT32 screen_update_slyspy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 101 | 91 | UINT32 screen_update_midres(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 102 | ||
| 103 | 92 | void baddudes_i8751_write(int data); |
| 104 | 93 | void birdtry_i8751_write(int data); |
| 105 | 94 | void dec0_i8751_write(int data); |
| 106 | 95 | void dec0_i8751_reset(); |
| 107 | 96 | void h6280_decrypt(const char *cputag); |
| 97 | DECLARE_WRITE_LINE_MEMBER(sound_irq); | |
| 98 | DECLARE_WRITE_LINE_MEMBER(sound_irq2); | |
| 99 | required_device<cpu_device> m_maincpu; | |
| 100 | required_device<cpu_device> m_audiocpu; | |
| 101 | optional_device<cpu_device> m_subcpu; | |
| 102 | optional_device<cpu_device> m_mcu; | |
| 103 | optional_device<msm5205_device> m_msm; | |
| 104 | required_device<palette_device> m_palette; | |
| 108 | 105 | }; |
| 109 | 106 | |
| 110 | 107 | |
| r242899 | r242900 | |
| 117 | 114 | |
| 118 | 115 | UINT8 m_automat_adpcm_byte; |
| 119 | 116 | int m_automat_msm5205_vclk_toggle; |
| 120 | UINT16 m_automat_scroll_regs[4]; | |
| 121 | ||
| 122 | 117 | DECLARE_WRITE16_MEMBER(automat_control_w); |
| 123 | 118 | DECLARE_WRITE8_MEMBER(automat_adpcm_w); |
| 124 | 119 | DECLARE_READ16_MEMBER( automat_palette_r ); |
| r242899 | r242900 | |
| 127 | 122 | { |
| 128 | 123 | COMBINE_DATA(&m_automat_scroll_regs[offset]); |
| 129 | 124 | } |
| 130 | DECLARE_WRITE_LINE_MEMBER(automat_vclk_cb); | |
| 131 | ||
| 132 | virtual void machine_start(); | |
| 133 | ||
| 125 | UINT16 m_automat_scroll_regs[4]; | |
| 126 | ||
| 134 | 127 | UINT32 screen_update_automat(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 135 | 128 | UINT32 screen_update_secretab(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 129 | DECLARE_WRITE_LINE_MEMBER(automat_vclk_cb); | |
| 136 | 130 | }; |
| r242899 | r242900 | |
|---|---|---|
| 14 | 14 | |
| 15 | 15 | /******************************************************************************/ |
| 16 | 16 | |
| 17 | void dec0_state::machine_start() | |
| 18 | { | |
| 19 | save_item(NAME(m_i8751_return)); | |
| 20 | save_item(NAME(m_i8751_command)); | |
| 21 | save_item(NAME(m_i8751_ports)); | |
| 22 | } | |
| 23 | ||
| 24 | 17 | READ16_MEMBER(dec0_state::dec0_controls_r) |
| 25 | 18 | { |
| 26 | 19 | switch (offset<<1) |
| r242899 | r242900 | |
| 301 | 294 | m_i8751_command=data; |
| 302 | 295 | |
| 303 | 296 | /* Writes to this address cause an IRQ to the i8751 microcontroller */ |
| 304 | if (m_game == 1) m_mcu->set_input_line(MCS51_INT1_LINE, ASSERT_LINE); | |
| 305 | if (m_game == 2) baddudes_i8751_write(data); | |
| 306 | if (m_game == 3) birdtry_i8751_write(data); | |
| 297 | if (m_GAME == 1) m_mcu->set_input_line(MCS51_INT1_LINE, ASSERT_LINE); | |
| 298 | if (m_GAME == 2) baddudes_i8751_write(data); | |
| 299 | if (m_GAME == 3) birdtry_i8751_write(data); | |
| 307 | 300 | |
| 308 | 301 | //logerror("%s: warning - write %02x to i8751\n",machine().describe_context(),data); |
| 309 | 302 | } |
| r242899 | r242900 | |
| 364 | 357 | RAM[0x1af] = 0x60; /* RTS prot area */ |
| 365 | 358 | RAM[0x1db] = 0x60; /* RTS prot area */ |
| 366 | 359 | RAM[0x21a] = 0x60; /* RTS prot area */ |
| 367 | ||
| 368 | save_item(NAME(m_hippodrm_msb)); | |
| 369 | save_item(NAME(m_hippodrm_lsb)); | |
| 370 | 360 | } |
| 371 | 361 | |
| 372 | 362 | DRIVER_INIT_MEMBER(dec0_state,slyspy) |
| r242899 | r242900 | |
| 377 | 367 | /* Slyspy sound cpu has some protection */ |
| 378 | 368 | RAM[0xf2d] = 0xea; |
| 379 | 369 | RAM[0xf2e] = 0xea; |
| 380 | ||
| 381 | save_item(NAME(m_slyspy_state)); | |
| 382 | 370 | } |
| 383 | 371 | |
| 384 | 372 | DRIVER_INIT_MEMBER(dec0_state,robocop) |
| r242899 | r242900 | |
| 388 | 376 | |
| 389 | 377 | DRIVER_INIT_MEMBER(dec0_state,baddudes) |
| 390 | 378 | { |
| 391 | m_ | |
| 379 | m_GAME = 2; | |
| 392 | 380 | } |
| 393 | 381 | |
| 394 | 382 | DRIVER_INIT_MEMBER(dec0_state,hbarrel) |
| 395 | 383 | { |
| 396 | m_ | |
| 384 | m_GAME = 1; | |
| 397 | 385 | } |
| 398 | 386 | |
| 399 | 387 | DRIVER_INIT_MEMBER(dec0_state,birdtry) |
| 400 | 388 | { |
| 401 | m_ | |
| 389 | m_GAME=3; | |
| 402 | 390 | } |
| r242899 | r242900 | |
|---|---|---|
| 339 | 339 | VIDEO_START_MEMBER(dec0_state,dec0_nodma) |
| 340 | 340 | { |
| 341 | 341 | save_item(NAME(m_pri)); |
| 342 | ||
| 342 | 343 | m_buffered_spriteram = m_spriteram; |
| 343 | save_pointer(NAME(m_buffered_spriteram), 0x800/2); | |
| 344 | 344 | } |
| 345 | 345 | |
| 346 | 346 | VIDEO_START_MEMBER(dec0_state,dec0) |
| 347 | 347 | { |
| 348 | | |
| 348 | VIDEO_START_CALL_MEMBER(dec0_nodma); | |
| 349 | 349 | m_buffered_spriteram = auto_alloc_array(machine(), UINT16, 0x800/2); |
| 350 | save_pointer(NAME(m_buffered_spriteram), 0x800/2); | |
| 351 | 350 | } |
| 352 | 351 | |
| 353 | 352 | /******************************************************************************/ |
| r242899 | r242900 | |
|---|---|---|
| 116 | 116 | save_pointer(NAME(m_pf_data), 0x4000/2); |
| 117 | 117 | save_pointer(NAME(m_pf_rowscroll), 0x2000/2); |
| 118 | 118 | save_pointer(NAME(m_pf_colscroll), 0x2000/2); |
| 119 | save_item(NAME(m_pf_control_0)); | |
| 120 | save_item(NAME(m_pf_control_1)); | |
| 121 | save_item(NAME(m_gfxcolmask)); | |
| 119 | save_pointer(NAME(m_pf_control_0), 8); | |
| 120 | save_pointer(NAME(m_pf_control_1), 8); | |
| 121 | ||
| 122 | 122 | save_item(NAME(m_rambank)); |
| 123 | 123 | } |
| 124 | 124 |
| r242899 | r242900 | |
|---|---|---|
| 14 | 14 | #include "modules/sound/none.h" |
| 15 | 15 | #include "modules/debugger/none.h" |
| 16 | 16 | #include "modules/debugger/debugint.h" |
| 17 | #include "modules/lib/osdobj_common.h" | |
| 18 | 17 | |
| 19 | 18 | extern bool g_print_verbose; |
| 20 | 19 | |
| 21 | const options_entry osd_options::s_option_entries[] = | |
| 22 | { | |
| 23 | { NULL, NULL, OPTION_HEADER, "OSD CLI OPTIONS" }, | |
| 24 | { OSDCOMMAND_LIST_MIDI_DEVICES ";mlist", "0", OPTION_COMMAND, "list available MIDI I/O devices" }, | |
| 25 | { OSDCOMMAND_LIST_NETWORK_ADAPTERS ";nlist", "0", OPTION_COMMAND, "list available network adapters" }, | |
| 26 | 20 | |
| 27 | // debugging options | |
| 28 | { NULL, NULL, OPTION_HEADER, "OSD DEBUGGING OPTIONS" }, | |
| 29 | { OSDOPTION_DEBUGGER, OSDOPTVAL_AUTO, OPTION_STRING, "debugger used : " }, | |
| 30 | { OSDOPTION_WATCHDOG ";wdog", "0", OPTION_INTEGER, "force the program to terminate if no updates within specified number of seconds" }, | |
| 31 | ||
| 32 | // performance options | |
| 33 | { NULL, NULL, OPTION_HEADER, "OSD PERFORMANCE OPTIONS" }, | |
| 34 | { OSDOPTION_MULTITHREADING ";mt", "0", OPTION_BOOLEAN, "enable multithreading; this enables rendering and blitting on a separate thread" }, | |
| 35 | { OSDOPTION_NUMPROCESSORS ";np", OSDOPTVAL_AUTO, OPTION_STRING, "number of processors; this overrides the number the system reports" }, | |
| 36 | { OSDOPTION_BENCH, "0", OPTION_INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" }, | |
| 37 | // video options | |
| 38 | { NULL, NULL, OPTION_HEADER, "OSD VIDEO OPTIONS" }, | |
| 39 | // OS X can be trusted to have working hardware OpenGL, so default to it on for the best user experience | |
| 40 | { OSDOPTION_VIDEO, OSDOPTVAL_AUTO, OPTION_STRING, "video output method: " }, | |
| 41 | { OSDOPTION_NUMSCREENS "(1-4)", "1", OPTION_INTEGER, "number of screens to create; usually, you want just one" }, | |
| 42 | { OSDOPTION_WINDOW ";w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" }, | |
| 43 | { OSDOPTION_MAXIMIZE ";max", "1", OPTION_BOOLEAN, "default to maximized windows; otherwise, windows will be minimized" }, | |
| 44 | { OSDOPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" }, | |
| 45 | { OSDOPTION_UNEVENSTRETCH ";ues", "1", OPTION_BOOLEAN, "allow non-integer stretch factors" }, | |
| 46 | { OSDOPTION_WAITVSYNC ";vs", "0", OPTION_BOOLEAN, "enable waiting for the start of VBLANK before flipping screens; reduces tearing effects" }, | |
| 47 | { OSDOPTION_SYNCREFRESH ";srf", "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" }, | |
| 48 | ||
| 49 | // per-window options | |
| 50 | { NULL, NULL, OPTION_HEADER, "OSD PER-WINDOW VIDEO OPTIONS" }, | |
| 51 | { OSDOPTION_SCREEN, OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, | |
| 52 | { OSDOPTION_ASPECT ";screen_aspect", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, | |
| 53 | { OSDOPTION_RESOLUTION ";r", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 54 | { OSDOPTION_VIEW, OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for all screens" }, | |
| 55 | ||
| 56 | { OSDOPTION_SCREEN "0", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, | |
| 57 | { OSDOPTION_ASPECT "0", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the first screen; 'auto' here will try to make a best guess" }, | |
| 58 | { OSDOPTION_RESOLUTION "0;r0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 59 | { OSDOPTION_VIEW "0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the first screen" }, | |
| 60 | ||
| 61 | { OSDOPTION_SCREEN "1", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the second screen; 'auto' here will try to make a best guess" }, | |
| 62 | { OSDOPTION_ASPECT "1", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the second screen; 'auto' here will try to make a best guess" }, | |
| 63 | { OSDOPTION_RESOLUTION "1;r1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 64 | { OSDOPTION_VIEW "1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the second screen" }, | |
| 65 | ||
| 66 | { OSDOPTION_SCREEN "2", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the third screen; 'auto' here will try to make a best guess" }, | |
| 67 | { OSDOPTION_ASPECT "2", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the third screen; 'auto' here will try to make a best guess" }, | |
| 68 | { OSDOPTION_RESOLUTION "2;r2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 69 | { OSDOPTION_VIEW "2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the third screen" }, | |
| 70 | ||
| 71 | { OSDOPTION_SCREEN "3", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the fourth screen; 'auto' here will try to make a best guess" }, | |
| 72 | { OSDOPTION_ASPECT "3", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" }, | |
| 73 | { OSDOPTION_RESOLUTION "3;r3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 74 | { OSDOPTION_VIEW "3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the fourth screen" }, | |
| 75 | ||
| 76 | // full screen options | |
| 77 | { NULL, NULL, OPTION_HEADER, "OSD FULL SCREEN OPTIONS" }, | |
| 78 | { OSDOPTION_SWITCHRES, "0", OPTION_BOOLEAN, "enable resolution switching" }, | |
| 79 | ||
| 80 | // sound options | |
| 81 | { NULL, NULL, OPTION_HEADER, "OSD SOUND OPTIONS" }, | |
| 82 | { OSDOPTION_SOUND, OSDOPTVAL_AUTO, OPTION_STRING, "sound output method: " }, | |
| 83 | { OSDOPTION_AUDIO_LATENCY "(1-5)", "2", OPTION_INTEGER, "set audio latency (increase to reduce glitches, decrease for responsiveness)" }, | |
| 84 | ||
| 85 | // End of list | |
| 86 | { NULL } | |
| 87 | }; | |
| 88 | ||
| 89 | osd_options::osd_options() | |
| 90 | : cli_options() | |
| 91 | { | |
| 92 | add_entries(osd_options::s_option_entries); | |
| 93 | }; | |
| 94 | ||
| 95 | ||
| 96 | 21 | //------------------------------------------------- |
| 97 | 22 | // osd_interface - constructor |
| 98 | 23 | //------------------------------------------------- |
| 99 | 24 | |
| 100 | osd_common_t::osd_common_t( | |
| 25 | osd_common_t::osd_common_t() | |
| 101 | 26 | : m_machine(NULL), |
| 102 | m_options(options), | |
| 103 | m_sound(NULL), | |
| 104 | m_debugger(NULL) | |
| 27 | m_sound(NULL), | |
| 28 | m_debugger(NULL) | |
| 105 | 29 | |
| 106 | 30 | { |
| 107 | 31 | } |
| 108 | 32 | |
| 109 | ||
| 110 | void osd_common_t::register_options() | |
| 33 | void osd_common_t::update_option(osd_options &options, const char * key, dynamic_array<const char *> &values) | |
| 111 | 34 | { |
| 112 | // Register video options and update options | |
| 113 | video_options_add("none", NULL); | |
| 114 | video_register(); | |
| 115 | update_option(OSDOPTION_VIDEO, m_video_names); | |
| 116 | ||
| 117 | // Register sound options and update options | |
| 118 | sound_options_add("none", OSD_SOUND_NONE); | |
| 119 | sound_register(); | |
| 120 | update_option(OSDOPTION_SOUND, m_sound_names); | |
| 121 | ||
| 122 | // Register debugger options and update options | |
| 123 | debugger_options_add("none", OSD_DEBUGGER_NONE); | |
| 124 | debugger_options_add("internal", OSD_DEBUGGER_INTERNAL); | |
| 125 | debugger_register(); | |
| 126 | update_option(OSDOPTION_DEBUGGER, m_debugger_names); | |
| 127 | } | |
| 128 | ||
| 129 | void osd_common_t::update_option(const char * key, dynamic_array<const char *> &values) | |
| 130 | { | |
| 131 | astring current_value(m_options.description(key)); | |
| 35 | astring current_value(options.description(key)); | |
| 132 | 36 | astring new_option_value(""); |
| 133 | 37 | for (int index = 0; index < values.count(); index++) |
| 134 | 38 | { |
| r242899 | r242900 | |
| 143 | 47 | new_option_value.cat(t); |
| 144 | 48 | } |
| 145 | 49 | // TODO: core_strdup() is leaked |
| 146 | | |
| 50 | options.set_description(key, core_strdup(current_value.cat(new_option_value).cstr())); | |
| 147 | 51 | } |
| 148 | 52 | |
| 53 | void osd_common_t::register_options(osd_options &options) | |
| 54 | { | |
| 55 | // Register video options and update options | |
| 56 | video_options_add("none", NULL); | |
| 57 | video_register(); | |
| 58 | update_option(options, OSDOPTION_VIDEO, m_video_names); | |
| 59 | ||
| 60 | // Register sound options and update options | |
| 61 | sound_options_add("none", OSD_SOUND_NONE); | |
| 62 | sound_register(); | |
| 63 | update_option(options, OSDOPTION_SOUND, m_sound_names); | |
| 64 | ||
| 65 | // Register debugger options and update options | |
| 66 | debugger_options_add("none", OSD_DEBUGGER_NONE); | |
| 67 | debugger_options_add("internal", OSD_DEBUGGER_INTERNAL); | |
| 68 | debugger_register(); | |
| 69 | update_option(options, OSDOPTION_DEBUGGER, m_debugger_names); | |
| 70 | } | |
| 71 | ||
| 72 | ||
| 149 | 73 | //------------------------------------------------- |
| 150 | 74 | // osd_interface - destructor |
| 151 | 75 | //------------------------------------------------- |
| r242899 | r242900 | |
| 243 | 167 | // is active. This gives any OSD debugger interface a chance to |
| 244 | 168 | // create all of its structures. |
| 245 | 169 | // |
| 246 | osd_debugger_type debugger = m_debugger_options.find(options().debugger()); | |
| 170 | osd_debugger_type debugger = m_debugger_options.find(machine().options().debugger()); | |
| 247 | 171 | if (debugger==NULL) |
| 248 | 172 | { |
| 249 | osd_printf_warning("debugger_init: option %s not found switching to auto\n",options().debugger()); | |
| 173 | osd_printf_warning("debugger_init: option %s not found switching to auto\n",machine().options().debugger()); | |
| 250 | 174 | debugger = m_debugger_options.find("auto"); |
| 251 | 175 | } |
| 252 | 176 | m_debugger = (*debugger)(*this); |
| r242899 | r242900 | |
| 298 | 222 | // It provides an array of stereo samples in L-R order which should be |
| 299 | 223 | // output at the configured sample_rate. |
| 300 | 224 | // |
| 301 | if (m_sound != NULL) | |
| 302 | m_sound->update_audio_stream(buffer,samples_this_frame); | |
| 225 | m_sound->update_audio_stream(buffer,samples_this_frame); | |
| 303 | 226 | } |
| 304 | 227 | |
| 305 | 228 | |
| r242899 | r242900 | |
| 316 | 239 | // while (attenuation++ < 0) |
| 317 | 240 | // volume /= 1.122018454; // = (10 ^ (1/20)) = 1dB |
| 318 | 241 | // |
| 319 | if (m_sound != NULL) | |
| 320 | m_sound->set_mastervolume(attenuation); | |
| 242 | m_sound->set_mastervolume(attenuation); | |
| 321 | 243 | } |
| 322 | 244 | |
| 323 | 245 | |
| r242899 | r242900 | |
| 379 | 301 | // get_slider_list - allocate and populate a |
| 380 | 302 | // list of OS-dependent slider values. |
| 381 | 303 | //------------------------------------------------- |
| 382 | ||
| 383 | 304 | void *osd_common_t::get_slider_list() |
| 384 | 305 | { |
| 385 | 306 | return NULL; |
| 386 | 307 | } |
| 387 | 308 | |
| 388 | //------------------------------------------------- | |
| 389 | // execute_command - execute a command not yet | |
| 390 | // handled by the core | |
| 391 | //------------------------------------------------- | |
| 392 | ||
| 393 | bool osd_common_t::execute_command(const char *command) | |
| 394 | { | |
| 395 | if (strcmp(command, OSDCOMMAND_LIST_NETWORK_ADAPTERS) == 0) | |
| 396 | { | |
| 397 | network_init(); | |
| 398 | osd_list_network_adapters(); | |
| 399 | network_exit(); | |
| 400 | return true; | |
| 401 | } | |
| 402 | else if (strcmp(command, OSDCOMMAND_LIST_MIDI_DEVICES) == 0) | |
| 403 | { | |
| 404 | osd_list_midi_devices(); | |
| 405 | return true; | |
| 406 | } | |
| 407 | ||
| 408 | return false; | |
| 409 | ||
| 410 | } | |
| 411 | ||
| 412 | 309 | void osd_common_t::init_subsystems() |
| 413 | 310 | { |
| 414 | 311 | if (!video_init()) |
| r242899 | r242900 | |
| 445 | 342 | |
| 446 | 343 | bool osd_common_t::sound_init() |
| 447 | 344 | { |
| 448 | osd_sound_type sound = m_sound_options.find(options().sound()); | |
| 345 | osd_sound_type sound = m_sound_options.find(machine().options().sound()); | |
| 449 | 346 | if (sound==NULL) |
| 450 | 347 | { |
| 451 | osd_printf_warning("sound_init: option %s not found switching to auto\n",options().sound()); | |
| 348 | osd_printf_warning("sound_init: option %s not found switching to auto\n",machine().options().sound()); | |
| 452 | 349 | sound = m_sound_options.find("auto"); |
| 453 | 350 | } |
| 454 | if (sound != NULL) | |
| 455 | m_sound = (*sound)(*this, machine()); | |
| 456 | else | |
| 457 | m_sound = NULL; | |
| 351 | m_sound = (*sound)(*this, machine()); | |
| 458 | 352 | return true; |
| 459 | 353 | } |
| 460 | 354 | |
| 461 | 355 | bool osd_common_t::no_sound() |
| 462 | 356 | { |
| 463 | return (strcmp(options().sound(),"none")==0) ? true : false; | |
| 357 | return (strcmp(machine().options().sound(),"none")==0) ? true : false; | |
| 464 | 358 | } |
| 465 | 359 | |
| 466 | 360 | void osd_common_t::video_register() |
| r242899 | r242900 | |
| 521 | 415 | |
| 522 | 416 | void osd_common_t::sound_exit() |
| 523 | 417 | { |
| 524 | if (m_sound != NULL) | |
| 525 | global_free(m_sound); | |
| 418 | global_free(m_sound); | |
| 526 | 419 | } |
| 527 | 420 | |
| 528 | 421 | void osd_common_t::input_exit() |
| r242899 | r242900 | |
| 566 | 459 | return osd_midi_init(); |
| 567 | 460 | } |
| 568 | 461 | |
| 462 | //------------------------------------------------- | |
| 463 | // list_midi_devices - list available midi devices | |
| 464 | //------------------------------------------------- | |
| 465 | ||
| 466 | void osd_common_t::list_midi_devices(void) | |
| 467 | { | |
| 468 | osd_list_midi_devices(); | |
| 469 | } | |
| 470 | ||
| 569 | 471 | void osd_common_t::midi_exit() |
| 570 | 472 | { |
| 571 | 473 | osd_midi_exit(); |
| r242899 | r242900 | |
|---|---|---|
| 14 | 14 | #define __OSDOBJ_COMMON__ |
| 15 | 15 | |
| 16 | 16 | #include "osdepend.h" |
| 17 | #include " | |
| 17 | #include "options.h" | |
| 18 | 18 | |
| 19 | //============================================================ | |
| 20 | // Defines | |
| 21 | //============================================================ | |
| 22 | 19 | |
| 23 | #define OSDCOMMAND_LIST_MIDI_DEVICES "listmidi" | |
| 24 | #define OSDCOMMAND_LIST_NETWORK_ADAPTERS "listnetwork" | |
| 20 | #if 0 | |
| 21 | // forward references | |
| 22 | class input_type_entry; | |
| 23 | class device_t; | |
| 24 | #endif | |
| 25 | 25 | |
| 26 | #define OSDOPTION_DEBUGGER "debugger" | |
| 27 | #define OSDOPTION_WATCHDOG "watchdog" | |
| 28 | ||
| 29 | #define OSDOPTION_MULTITHREADING "multithreading" | |
| 30 | #define OSDOPTION_NUMPROCESSORS "numprocessors" | |
| 31 | #define OSDOPTION_BENCH "bench" | |
| 32 | ||
| 33 | #define OSDOPTION_VIDEO "video" | |
| 34 | #define OSDOPTION_NUMSCREENS "numscreens" | |
| 35 | #define OSDOPTION_WINDOW "window" | |
| 36 | #define OSDOPTION_MAXIMIZE "maximize" | |
| 37 | #define OSDOPTION_KEEPASPECT "keepaspect" | |
| 38 | #define OSDOPTION_UNEVENSTRETCH "unevenstretch" | |
| 39 | #define OSDOPTION_WAITVSYNC "waitvsync" | |
| 40 | #define OSDOPTION_SYNCREFRESH "syncrefresh" | |
| 41 | ||
| 42 | #define OSDOPTION_SCREEN "screen" | |
| 43 | #define OSDOPTION_ASPECT "aspect" | |
| 44 | #define OSDOPTION_RESOLUTION "resolution" | |
| 45 | #define OSDOPTION_VIEW "view" | |
| 46 | ||
| 47 | #define OSDOPTION_SWITCHRES "switchres" | |
| 48 | ||
| 49 | #define OSDOPTION_SOUND "sound" | |
| 50 | #define OSDOPTION_AUDIO_LATENCY "audio_latency" | |
| 51 | ||
| 52 | #define OSDOPTVAL_AUTO "auto" | |
| 53 | ||
| 54 | //============================================================ | |
| 55 | // TYPE DEFINITIONS | |
| 56 | //============================================================ | |
| 57 | ||
| 58 | /* FIXME: core_options inherits from osd_options. This will force any | |
| 59 | * future osd implementation to use the options below. Actually, these | |
| 60 | * options are *private* to the osd_core. This object should actually be an | |
| 61 | * accessor object. Later ... | |
| 62 | */ | |
| 63 | ||
| 64 | /* FIXME: core_options inherits from osd_options. This will force any | |
| 65 | * future osd implementation to use the options below. Actually, these | |
| 66 | * options are *private* to the osd_core. This object should actually be an | |
| 67 | * accessor object. Later ... | |
| 68 | */ | |
| 69 | ||
| 70 | class osd_options : public cli_options | |
| 71 | { | |
| 72 | public: | |
| 73 | // construction/destruction | |
| 74 | osd_options(); | |
| 75 | ||
| 76 | // debugging options | |
| 77 | const char *debugger() const { return value(OSDOPTION_DEBUGGER); } | |
| 78 | int watchdog() const { return int_value(OSDOPTION_WATCHDOG); } | |
| 79 | ||
| 80 | // performance options | |
| 81 | bool multithreading() const { return bool_value(OSDOPTION_MULTITHREADING); } | |
| 82 | const char *numprocessors() const { return value(OSDOPTION_NUMPROCESSORS); } | |
| 83 | int bench() const { return int_value(OSDOPTION_BENCH); } | |
| 84 | ||
| 85 | // video options | |
| 86 | const char *video() const { return value(OSDOPTION_VIDEO); } | |
| 87 | int numscreens() const { return int_value(OSDOPTION_NUMSCREENS); } | |
| 88 | bool window() const { return bool_value(OSDOPTION_WINDOW); } | |
| 89 | bool maximize() const { return bool_value(OSDOPTION_MAXIMIZE); } | |
| 90 | bool keep_aspect() const { return bool_value(OSDOPTION_KEEPASPECT); } | |
| 91 | bool uneven_stretch() const { return bool_value(OSDOPTION_UNEVENSTRETCH); } | |
| 92 | bool wait_vsync() const { return bool_value(OSDOPTION_WAITVSYNC); } | |
| 93 | bool sync_refresh() const { return bool_value(OSDOPTION_SYNCREFRESH); } | |
| 94 | ||
| 95 | // per-window options | |
| 96 | const char *screen() const { return value(OSDOPTION_SCREEN); } | |
| 97 | const char *aspect() const { return value(OSDOPTION_ASPECT); } | |
| 98 | const char *resolution() const { return value(OSDOPTION_RESOLUTION); } | |
| 99 | const char *view() const { return value(OSDOPTION_VIEW); } | |
| 100 | const char *screen(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_SCREEN, index)); } | |
| 101 | const char *aspect(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_ASPECT, index)); } | |
| 102 | const char *resolution(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_RESOLUTION, index)); } | |
| 103 | const char *view(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_VIEW, index)); } | |
| 104 | ||
| 105 | // full screen options | |
| 106 | bool switch_res() const { return bool_value(OSDOPTION_SWITCHRES); } | |
| 107 | ||
| 108 | // sound options | |
| 109 | const char *sound() const { return value(OSDOPTION_SOUND); } | |
| 110 | int audio_latency() const { return int_value(OSDOPTION_AUDIO_LATENCY); } | |
| 111 | ||
| 112 | private: | |
| 113 | static const options_entry s_option_entries[]; | |
| 114 | }; | |
| 115 | ||
| 116 | 26 | class osd_sound_interface; |
| 117 | 27 | class osd_debugger_interface; |
| 118 | 28 | |
| r242899 | r242900 | |
| 130 | 40 | { |
| 131 | 41 | public: |
| 132 | 42 | // construction/destruction |
| 133 | osd_common_t( | |
| 43 | osd_common_t(); | |
| 134 | 44 | virtual ~osd_common_t(); |
| 135 | 45 | |
| 136 | // FIXME: simply option handling | |
| 137 | virtual void register_options(); | |
| 46 | virtual void register_options(osd_options &options); | |
| 138 | 47 | |
| 139 | 48 | // general overridables |
| 140 | 49 | virtual void init(running_machine &machine); |
| r242899 | r242900 | |
| 160 | 69 | // video overridables |
| 161 | 70 | virtual void *get_slider_list(); |
| 162 | 71 | |
| 163 | // command option overrides | |
| 164 | virtual bool execute_command(const char *command); | |
| 72 | // midi overridables | |
| 73 | // FIXME: this should return a list of devices, not list them on stdout | |
| 74 | virtual void list_midi_devices(void); | |
| 165 | 75 | |
| 76 | virtual void list_network_adapters() | |
| 77 | { | |
| 78 | network_init(); | |
| 79 | osd_list_network_adapters(); | |
| 80 | network_exit(); | |
| 81 | } | |
| 82 | ||
| 83 | ||
| 166 | 84 | // FIXME: everything below seems to be osd specific and not part of |
| 167 | 85 | // this INTERFACE but part of the osd IMPLEMENTATION |
| 168 | 86 | |
| r242899 | r242900 | |
| 183 | 101 | virtual bool sound_init(); |
| 184 | 102 | virtual void sound_register(); |
| 185 | 103 | |
| 104 | virtual bool input_init(); | |
| 105 | virtual void input_pause(); | |
| 186 | 106 | virtual void input_resume(); |
| 187 | 107 | virtual bool output_init(); |
| 188 | 108 | virtual bool network_init(); |
| r242899 | r242900 | |
| 203 | 123 | virtual void sound_options_add(const char *name, osd_sound_type type); |
| 204 | 124 | virtual void debugger_options_add(const char *name, osd_debugger_type type); |
| 205 | 125 | |
| 206 | osd_options &options() { return m_options; } | |
| 207 | ||
| 208 | protected: | |
| 209 | virtual bool input_init(); | |
| 210 | virtual void input_pause(); | |
| 211 | ||
| 212 | 126 | private: |
| 213 | 127 | // internal state |
| 214 | 128 | running_machine * m_machine; |
| 215 | osd_options& m_options; | |
| 216 | 129 | |
| 217 | void update_option(const char * key, dynamic_array<const char *> &values); | |
| 130 | void update_option(osd_options &options, const char * key, dynamic_array<const char *> &values); | |
| 218 | 131 | |
| 219 | 132 | protected: |
| 220 | 133 | osd_sound_interface* m_sound; |
| r0 | r242900 | |
|---|---|---|
| 1 | #include "osdepend.h" | |
| 2 | ||
| 3 | const options_entry osd_options::s_option_entries[] = | |
| 4 | { | |
| 5 | // debugging options | |
| 6 | { NULL, NULL, OPTION_HEADER, "OSD DEBUGGING OPTIONS" }, | |
| 7 | { OSDOPTION_LOG, "0", OPTION_BOOLEAN, "generate an error.log file" }, | |
| 8 | { OSDOPTION_VERBOSE ";v", "0", OPTION_BOOLEAN, "display additional diagnostic information" }, | |
| 9 | { OSDOPTION_DEBUG ";d", "0", OPTION_BOOLEAN, "enable/disable debugger" }, | |
| 10 | { OSDOPTION_DEBUGGER, OSDOPTVAL_AUTO, OPTION_STRING, "debugger used : " }, | |
| 11 | { OSDOPTION_OSLOG, "0", OPTION_BOOLEAN, "output error.log data to the system debugger" }, | |
| 12 | { OSDOPTION_WATCHDOG ";wdog", "0", OPTION_INTEGER, "force the program to terminate if no updates within specified number of seconds" }, | |
| 13 | ||
| 14 | // performance options | |
| 15 | { NULL, NULL, OPTION_HEADER, "OSD PERFORMANCE OPTIONS" }, | |
| 16 | { OSDOPTION_MULTITHREADING ";mt", "0", OPTION_BOOLEAN, "enable multithreading; this enables rendering and blitting on a separate thread" }, | |
| 17 | { OSDOPTION_NUMPROCESSORS ";np", OSDOPTVAL_AUTO, OPTION_STRING, "number of processors; this overrides the number the system reports" }, | |
| 18 | { OSDOPTION_BENCH, "0", OPTION_INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" }, | |
| 19 | // video options | |
| 20 | { NULL, NULL, OPTION_HEADER, "OSD VIDEO OPTIONS" }, | |
| 21 | // OS X can be trusted to have working hardware OpenGL, so default to it on for the best user experience | |
| 22 | { OSDOPTION_VIDEO, OSDOPTVAL_AUTO, OPTION_STRING, "video output method: " }, | |
| 23 | { OSDOPTION_NUMSCREENS "(1-4)", "1", OPTION_INTEGER, "number of screens to create; usually, you want just one" }, | |
| 24 | { OSDOPTION_WINDOW ";w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" }, | |
| 25 | { OSDOPTION_MAXIMIZE ";max", "1", OPTION_BOOLEAN, "default to maximized windows; otherwise, windows will be minimized" }, | |
| 26 | { OSDOPTION_KEEPASPECT ";ka", "1", OPTION_BOOLEAN, "constrain to the proper aspect ratio" }, | |
| 27 | { OSDOPTION_UNEVENSTRETCH ";ues", "1", OPTION_BOOLEAN, "allow non-integer stretch factors" }, | |
| 28 | { OSDOPTION_WAITVSYNC ";vs", "0", OPTION_BOOLEAN, "enable waiting for the start of VBLANK before flipping screens; reduces tearing effects" }, | |
| 29 | { OSDOPTION_SYNCREFRESH ";srf", "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" }, | |
| 30 | ||
| 31 | // per-window options | |
| 32 | { NULL, NULL, OPTION_HEADER, "OSD PER-WINDOW VIDEO OPTIONS" }, | |
| 33 | { OSDOPTION_SCREEN, OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, | |
| 34 | { OSDOPTION_ASPECT ";screen_aspect", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" }, | |
| 35 | { OSDOPTION_RESOLUTION ";r", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 36 | { OSDOPTION_VIEW, OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for all screens" }, | |
| 37 | ||
| 38 | { OSDOPTION_SCREEN "0", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" }, | |
| 39 | { OSDOPTION_ASPECT "0", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the first screen; 'auto' here will try to make a best guess" }, | |
| 40 | { OSDOPTION_RESOLUTION "0;r0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 41 | { OSDOPTION_VIEW "0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the first screen" }, | |
| 42 | ||
| 43 | { OSDOPTION_SCREEN "1", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the second screen; 'auto' here will try to make a best guess" }, | |
| 44 | { OSDOPTION_ASPECT "1", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the second screen; 'auto' here will try to make a best guess" }, | |
| 45 | { OSDOPTION_RESOLUTION "1;r1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 46 | { OSDOPTION_VIEW "1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the second screen" }, | |
| 47 | ||
| 48 | { OSDOPTION_SCREEN "2", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the third screen; 'auto' here will try to make a best guess" }, | |
| 49 | { OSDOPTION_ASPECT "2", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the third screen; 'auto' here will try to make a best guess" }, | |
| 50 | { OSDOPTION_RESOLUTION "2;r2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 51 | { OSDOPTION_VIEW "2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the third screen" }, | |
| 52 | ||
| 53 | { OSDOPTION_SCREEN "3", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the fourth screen; 'auto' here will try to make a best guess" }, | |
| 54 | { OSDOPTION_ASPECT "3", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" }, | |
| 55 | { OSDOPTION_RESOLUTION "3;r3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" }, | |
| 56 | { OSDOPTION_VIEW "3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the fourth screen" }, | |
| 57 | ||
| 58 | // full screen options | |
| 59 | { NULL, NULL, OPTION_HEADER, "OSD FULL SCREEN OPTIONS" }, | |
| 60 | { OSDOPTION_SWITCHRES, "0", OPTION_BOOLEAN, "enable resolution switching" }, | |
| 61 | ||
| 62 | // sound options | |
| 63 | { NULL, NULL, OPTION_HEADER, "OSD SOUND OPTIONS" }, | |
| 64 | { OSDOPTION_SOUND, OSDOPTVAL_AUTO, OPTION_STRING, "sound output method: " }, | |
| 65 | { OSDOPTION_AUDIO_LATENCY "(1-5)", "2", OPTION_INTEGER, "set audio latency (increase to reduce glitches, decrease for responsiveness)" }, | |
| 66 | ||
| 67 | // End of list | |
| 68 | { NULL } | |
| 69 | }; |
| r242899 | r242900 | |
|---|---|---|
| 16 | 16 | #include "emucore.h" |
| 17 | 17 | #include "osdcore.h" |
| 18 | 18 | #include "unicode.h" |
| 19 | #include "cliopts.h" | |
| 20 | 19 | |
| 21 | 20 | // forward references |
| 22 | 21 | class input_type_entry; // FIXME: including emu.h does not work because emu.h includes osdepend.h |
| 23 | 22 | |
| 23 | //============================================================ | |
| 24 | // Defines | |
| 25 | //============================================================ | |
| 24 | 26 | |
| 27 | /* FIXME: void cli_frontend::listnetworkadapters should be | |
| 28 | * moved here. | |
| 29 | */ | |
| 30 | #include "options.h" | |
| 31 | ||
| 32 | #define OSDOPTION_LOG "log" | |
| 33 | #define OSDOPTION_VERBOSE "verbose" | |
| 34 | #define OSDOPTION_DEBUG "debug" | |
| 35 | #define OSDOPTION_DEBUGGER "debugger" | |
| 36 | #define OSDOPTION_OSLOG "oslog" | |
| 37 | #define OSDOPTION_WATCHDOG "watchdog" | |
| 38 | ||
| 39 | #define OSDOPTION_MULTITHREADING "multithreading" | |
| 40 | #define OSDOPTION_NUMPROCESSORS "numprocessors" | |
| 41 | #define OSDOPTION_BENCH "bench" | |
| 42 | ||
| 43 | #define OSDOPTION_VIDEO "video" | |
| 44 | #define OSDOPTION_NUMSCREENS "numscreens" | |
| 45 | #define OSDOPTION_WINDOW "window" | |
| 46 | #define OSDOPTION_MAXIMIZE "maximize" | |
| 47 | #define OSDOPTION_KEEPASPECT "keepaspect" | |
| 48 | #define OSDOPTION_UNEVENSTRETCH "unevenstretch" | |
| 49 | #define OSDOPTION_WAITVSYNC "waitvsync" | |
| 50 | #define OSDOPTION_SYNCREFRESH "syncrefresh" | |
| 51 | ||
| 52 | #define OSDOPTION_SCREEN "screen" | |
| 53 | #define OSDOPTION_ASPECT "aspect" | |
| 54 | #define OSDOPTION_RESOLUTION "resolution" | |
| 55 | #define OSDOPTION_VIEW "view" | |
| 56 | ||
| 57 | #define OSDOPTION_SWITCHRES "switchres" | |
| 58 | ||
| 59 | #define OSDOPTION_SOUND "sound" | |
| 60 | #define OSDOPTION_AUDIO_LATENCY "audio_latency" | |
| 61 | ||
| 62 | #define OSDOPTVAL_AUTO "auto" | |
| 63 | ||
| 25 | 64 | //============================================================ |
| 26 | 65 | // TYPE DEFINITIONS |
| 27 | 66 | //============================================================ |
| 28 | 67 | |
| 68 | /* FIXME: core_options inherits from osd_options. This will force any | |
| 69 | * future osd implementation to use the options below. Actually, these | |
| 70 | * options are *private* to the osd_core. This object should actually be an | |
| 71 | * accessor object. Later ... | |
| 72 | */ | |
| 73 | ||
| 74 | class osd_options : public core_options | |
| 75 | { | |
| 76 | public: | |
| 77 | // construction/destruction | |
| 78 | osd_options() : core_options() {}; | |
| 79 | ||
| 80 | // debugging options | |
| 81 | bool verbose() const { return bool_value(OSDOPTION_VERBOSE); } | |
| 82 | bool log() const { return bool_value(OSDOPTION_LOG); } | |
| 83 | bool debug() const { return bool_value(OSDOPTION_DEBUG); } | |
| 84 | const char *debugger() const { return value(OSDOPTION_DEBUGGER); } | |
| 85 | bool oslog() const { return bool_value(OSDOPTION_OSLOG); } | |
| 86 | int watchdog() const { return int_value(OSDOPTION_WATCHDOG); } | |
| 87 | ||
| 88 | // performance options | |
| 89 | bool multithreading() const { return bool_value(OSDOPTION_MULTITHREADING); } | |
| 90 | const char *numprocessors() const { return value(OSDOPTION_NUMPROCESSORS); } | |
| 91 | int bench() const { return int_value(OSDOPTION_BENCH); } | |
| 92 | ||
| 93 | // video options | |
| 94 | const char *video() const { return value(OSDOPTION_VIDEO); } | |
| 95 | int numscreens() const { return int_value(OSDOPTION_NUMSCREENS); } | |
| 96 | bool window() const { return bool_value(OSDOPTION_WINDOW); } | |
| 97 | bool maximize() const { return bool_value(OSDOPTION_MAXIMIZE); } | |
| 98 | bool keep_aspect() const { return bool_value(OSDOPTION_KEEPASPECT); } | |
| 99 | bool uneven_stretch() const { return bool_value(OSDOPTION_UNEVENSTRETCH); } | |
| 100 | bool wait_vsync() const { return bool_value(OSDOPTION_WAITVSYNC); } | |
| 101 | bool sync_refresh() const { return bool_value(OSDOPTION_SYNCREFRESH); } | |
| 102 | ||
| 103 | // per-window options | |
| 104 | const char *screen() const { return value(OSDOPTION_SCREEN); } | |
| 105 | const char *aspect() const { return value(OSDOPTION_ASPECT); } | |
| 106 | const char *resolution() const { return value(OSDOPTION_RESOLUTION); } | |
| 107 | const char *view() const { return value(OSDOPTION_VIEW); } | |
| 108 | const char *screen(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_SCREEN, index)); } | |
| 109 | const char *aspect(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_ASPECT, index)); } | |
| 110 | const char *resolution(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_RESOLUTION, index)); } | |
| 111 | const char *view(int index) const { astring temp; return value(temp.format("%s%d", OSDOPTION_VIEW, index)); } | |
| 112 | ||
| 113 | // full screen options | |
| 114 | bool switch_res() const { return bool_value(OSDOPTION_SWITCHRES); } | |
| 115 | ||
| 116 | // sound options | |
| 117 | const char *sound() const { return value(OSDOPTION_SOUND); } | |
| 118 | int audio_latency() const { return int_value(OSDOPTION_AUDIO_LATENCY); } | |
| 119 | ||
| 120 | void add_osd_options() | |
| 121 | { | |
| 122 | this->add_entries(s_option_entries); | |
| 123 | } | |
| 124 | private: | |
| 125 | static const options_entry s_option_entries[]; | |
| 126 | }; | |
| 127 | ||
| 128 | ||
| 29 | 129 | // FIXME: We can do better than this |
| 30 | 130 | typedef void *osd_font; |
| 31 | 131 | |
| r242899 | r242900 | |
| 49 | 149 | virtual void set_mastervolume(int attenuation) = 0; |
| 50 | 150 | virtual bool no_sound() = 0; |
| 51 | 151 | |
| 152 | ||
| 52 | 153 | // input overridables |
| 53 | 154 | virtual void customize_input_type_list(simple_list<input_type_entry> &typelist) = 0; |
| 54 | 155 | |
| r242899 | r242900 | |
| 60 | 161 | // video overridables |
| 61 | 162 | virtual void *get_slider_list() = 0; // FIXME: returns slider_state * |
| 62 | 163 | |
| 63 | // command option overrides | |
| 64 | virtual bool execute_command(const char *command) = 0; | |
| 164 | // midi overridables | |
| 165 | // FIXME: this should return a list of devices, not list them on stdout, even better | |
| 166 | // move this to OSD_OPTIONS | |
| 167 | virtual void list_midi_devices(void) = 0; | |
| 65 | 168 | |
| 169 | virtual void list_network_adapters() = 0; | |
| 170 | ||
| 66 | 171 | }; |
| 67 | 172 | |
| 68 | 173 | #endif /* __OSDEPEND_H__ */ |
| r242899 | r242900 | |
|---|---|---|
| 120 | 120 | // TYPE DEFINITIONS |
| 121 | 121 | //============================================================ |
| 122 | 122 | |
| 123 | class sdl_options : public | |
| 123 | class sdl_options : public cli_options | |
| 124 | 124 | { |
| 125 | 125 | public: |
| 126 | 126 | // construction/destruction |
| r242899 | r242900 | |
| 181 | 181 | { |
| 182 | 182 | public: |
| 183 | 183 | // construction/destruction |
| 184 | sdl_osd_interface( | |
| 184 | sdl_osd_interface(); | |
| 185 | 185 | virtual ~sdl_osd_interface(); |
| 186 | 186 | |
| 187 | 187 | // general overridables |
| r242899 | r242900 | |
| 220 | 220 | #endif |
| 221 | 221 | //virtual void midi_exit(); |
| 222 | 222 | |
| 223 | sdl_options &options() { return m_options; } | |
| 224 | ||
| 225 | 223 | private: |
| 226 | 224 | virtual void osd_exit(); |
| 227 | sdl_options &m_options; | |
| 228 | 225 | |
| 229 | 226 | watchdog *m_watchdog; |
| 230 | 227 |
| r242899 | r242900 | |
|---|---|---|
| 255 | 255 | //============================================================ |
| 256 | 256 | |
| 257 | 257 | sdl_options::sdl_options() |
| 258 | : osd_options() | |
| 259 | 258 | { |
| 260 | 259 | astring ini_path(INI_PATH); |
| 261 | add_entries(s | |
| 260 | add_entries(s_option_entries); | |
| 262 | 261 | ini_path.replace(0, "APP_NAME", emulator_info::get_appname_lower()); |
| 263 | 262 | set_default_value(SDLOPTION_INIPATH, ini_path.cstr()); |
| 264 | 263 | } |
| r242899 | r242900 | |
| 334 | 333 | #endif |
| 335 | 334 | |
| 336 | 335 | { |
| 337 | sdl_options options; | |
| 338 | sdl_osd_interface osd(options); | |
| 339 | osd.register_options(); | |
| 336 | sdl_osd_interface osd; | |
| 337 | sdl_options options; | |
| 338 | osd.register_options(options); | |
| 340 | 339 | cli_frontend frontend(options, osd); |
| 341 | 340 | res = frontend.execute(argc, argv); |
| 342 | 341 | } |
| r242899 | r242900 | |
| 381 | 380 | // constructor |
| 382 | 381 | //============================================================ |
| 383 | 382 | |
| 384 | sdl_osd_interface::sdl_osd_interface(sdl_options &options) | |
| 385 | : osd_common_t(options), m_options(options) | |
| 383 | sdl_osd_interface::sdl_osd_interface() | |
| 386 | 384 | { |
| 387 | 385 | m_watchdog = NULL; |
| 388 | 386 | } |
| r242899 | r242900 | |
|---|---|---|
| 421 | 421 | DWORD result = 0; |
| 422 | 422 | { |
| 423 | 423 | windows_options options; |
| 424 | windows_osd_interface osd(options); | |
| 425 | osd.register_options(); | |
| 424 | windows_osd_interface osd; | |
| 425 | osd.register_options(options); | |
| 426 | 426 | cli_frontend frontend(options, osd); |
| 427 | 427 | result = frontend.execute(argc, argv); |
| 428 | 428 | } |
| r242899 | r242900 | |
| 437 | 437 | //============================================================ |
| 438 | 438 | |
| 439 | 439 | windows_options::windows_options() |
| 440 | : osd_options() | |
| 441 | 440 | { |
| 442 | 441 | add_entries(s_option_entries); |
| 443 | 442 | } |
| r242899 | r242900 | |
| 513 | 512 | // constructor |
| 514 | 513 | //============================================================ |
| 515 | 514 | |
| 516 | windows_osd_interface::windows_osd_interface(windows_options &options) | |
| 517 | : osd_common_t(options) | |
| 515 | windows_osd_interface::windows_osd_interface() | |
| 518 | 516 | { |
| 519 | 517 | } |
| 520 | 518 |
| r242899 | r242900 | |
|---|---|---|
| 114 | 114 | // TYPE DEFINITIONS |
| 115 | 115 | //============================================================ |
| 116 | 116 | |
| 117 | class windows_options : public | |
| 117 | class windows_options : public cli_options | |
| 118 | 118 | { |
| 119 | 119 | public: |
| 120 | 120 | // construction/destruction |
| r242899 | r242900 | |
| 239 | 239 | { |
| 240 | 240 | public: |
| 241 | 241 | // construction/destruction |
| 242 | windows_osd_interface( | |
| 242 | windows_osd_interface(); | |
| 243 | 243 | virtual ~windows_osd_interface(); |
| 244 | 244 | |
| 245 | 245 | // general overridables |
| r242899 | r242900 | |
|---|---|---|
| 6 | 6 | // |
| 7 | 7 | //============================================================ |
| 8 | 8 | |
| 9 | #ifndef _WIN32_WINNT | |
| 9 | #ifdef PTR64 | |
| 10 | #define _WIN32_WINNT 0x0601 // Windows 7 | |
| 11 | #else | |
| 10 | 12 | #define _WIN32_WINNT 0x0501 // Windows XP |
| 11 | 13 | #endif |
| 12 | 14 |
| https://github.com/mamedev/mame/commit/5ed8de79e853415201e34c2d2693a84cf59c270a |
| Previous | 199869 Revisions | Next |