# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: colin@gibibit.com-20080804171055-36h7yem24erv5fy8 # target_branch: http://grub.gibibit.com/bzr/trunk-clean # testament_sha1: 1c89c142bccacc692e7e4d96fe51b2cbe5afc77e # timestamp: 2008-08-04 10:15:25 -0700 # source_branch: http://grub.gibibit.com/bzr/gfxmenu # base_revision_id: colin@gibibit.com-20080803040022-bxhp6libdkx40muv # # Begin patch === added file 'commands/luagfx.c' --- commands/luagfx.c 1970-01-01 00:00:00 +0000 +++ commands/luagfx.c 2008-08-04 17:10:55 +0000 @@ -0,0 +1,152 @@ +/* luagfx.c - Test of extending Lua to access GRUB graphics. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_luagfx (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + /* Load the file into ``buf``. */ + const char *filename = "/luagfx.lua"; + grub_file_t f; + grub_errno = GRUB_ERR_NONE; + f = grub_file_open (filename); + if (! f) + return grub_errno; + grub_size_t sz = grub_file_size (f); + char *buf = grub_malloc (sz); + if (! buf) + return grub_errno; + if ((grub_size_t) grub_file_read (f, buf, sz) != sz) + { + grub_free (buf); + grub_file_close (f); + return grub_errno; + } + grub_file_close (f); + + /* Display info on the file and its loaded contents. */ + grub_printf ("Loaded %u bytes from %s.", sz, filename); + + /* Execute some Lua code. */ + int err; + lua_State *L = lua_open (); + luaL_openlibs (L); + + err = luaL_loadstring (L, "print('Hello from a Lua string.')"); + if (err) + { + grub_printf ("Lua load string error: %s\n", lua_tostring (L, -1)); + lua_pop (L, 1); /* Pop the error message. */ + goto end; + } + + err = lua_pcall (L, 0, 0, 0); + if (err) + { + grub_printf ("Lua pcall string chunk error: %s\n", lua_tostring (L, -1)); + lua_pop (L, 1); /* Pop the error message. */ + goto end; + } + + err = luaL_loadbuffer (L, buf, sz, filename); + grub_free (buf); + if (err) + { + grub_printf ("Lua error: %s\n", lua_tostring (L, -1)); + lua_pop (L, 1); /* Pop the error message. */ + goto end; + } + + err = lua_pcall (L, 0, 0, 0); + if (err) + { + grub_printf ("Error in lua_pcall(): %s\n", lua_tostring (L, -1)); + goto end; + } + grub_printf ("Lua chunk executed\n"); + + lua_getglobal (L, "main"); + if (lua_isnoneornil (L, -1)) + { + grub_printf ("Error: symbol 'main' does not exist.\n"); + goto end; + } + + err = lua_pcall (L, 0, 0, 0); + if (err) + { + grub_printf ("Error in lua_pcall(): %s\n", lua_tostring (L, -1)); + goto end; + } + grub_printf ("Lua function 'main' executed\n"); + + grub_lua_load_grub_packages (L); + grub_printf ("GRUB Lua packages loaded\n"); + + lua_getglobal (L, "videotest"); + if (lua_isnoneornil (L, -1)) + { + grub_printf ("Error: symbol 'videotest' does not exist.\n"); + goto end; + } + + err = lua_pcall (L, 0, 0, 0); + if (err) + { + grub_printf ("Error in lua_pcall(): %s\n", lua_tostring (L, -1)); + goto end; + } + grub_printf ("Lua function 'videotest' executed\n"); + +end: + lua_close (L); + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT (luagfx) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("luagfx", + grub_cmd_luagfx, GRUB_COMMAND_FLAG_BOTH, + "luagfx", "Test of Lua graphics", 0); +} + +GRUB_MOD_FINI (luagfx) +{ + grub_unregister_command ("luagfx"); +} === added file 'commands/luagfx.lua' --- commands/luagfx.lua 1970-01-01 00:00:00 +0000 +++ commands/luagfx.lua 2008-08-04 17:10:55 +0000 @@ -0,0 +1,70 @@ +print("This is luagfx.lua, the file chunk.") + +function main() + print("Hello, world!! This is the function 'main' from Lua!") +end + +function delay(ms) + local stop = sys.get_time_ms() + ms + while stop - sys.get_time_ms() > 0 do + end +end + +function videotest() +-- video.set_graphics_mode() + local seed = 42373 + local function rand(min,max) + seed = seed * 97 + 17 * min * max + return seed % (max - min + 1) + min + end + + local strings = + { + "Hello, world!", + "GRUB rocks!", + "What's up?", + "Do the Dew!", + "Lua!" + } + local function new_random_word() + local w={} + w.speed = rand(5,15) + w.x = rand(-200, -100) + w.y = rand(40, 440) + w.text = strings[rand(1, #strings)] + w.color = {r=rand(0,255), g=rand(0,255), b=rand(0,255)} + return w + end + + local words={} + while table.getn(words) < 10 do + table.insert(words, new_random_word()) + end + while not input.checkkey() do + video.fill_rect({r=255, g=255, b=255}, 0, 0, 640, 480) + + -- Draw the words. + for _, w in ipairs(words) do + video.draw_string(w.text, "Helvetica Bold 18", + w.color, w.x, w.y) + end + video.swap_buffers() + + -- Update the word positions and + -- refresh words when they reach the edge. + for i,w in ipairs(words) do + w.x = w.x + w.speed + if w.x >= 640 then + words[i] = new_random_word() + end + end + + -- Delay a moment. + delay(12) + end + + -- Eat the keypress. + input.getkey() +-- video.set_text_mode() +end + === modified file 'conf/common.rmk' --- conf/common.rmk 2008-08-03 04:00:22 +0000 +++ conf/common.rmk 2008-08-04 17:10:55 +0000 @@ -289,7 +289,7 @@ gfxmenu/view.c \ gfxmenu/widget-box.c \ gfxmenu/stringutil.c -gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS) +gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/lua gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS) # For boot.mod. @@ -393,7 +393,9 @@ crc_mod_LDFLAGS = $(COMMON_LDFLAGS) # Misc. -pkglib_MODULES += gzio.mod bufio.mod elf.mod +pkglib_MODULES += gzio.mod bufio.mod elf.mod \ + lua.mod luacmd.mod \ + luagfx.mod luagrub.mod # For elf.mod. elf_mod_SOURCES = kern/elf.c @@ -409,3 +411,32 @@ bufio_mod_SOURCES = io/bufio.c bufio_mod_CFLAGS = $(COMMON_CFLAGS) bufio_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lua.mod. +lua_mod_SOURCES = lua/lapi.c lua/lcode.c lua/ldebug.c lua/ldo.c lua/ldump.c \ + lua/lfunc.c lua/lgc.c lua/llex.c lua/lmem.c lua/lobject.c \ + lua/lopcodes.c lua/lparser.c lua/lstate.c lua/lstring.c \ + lua/ltable.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c \ + lua/lauxlib.c lua/linit.c lua/lbaselib.c lua/ldblib.c lua/ltablib.c \ + lua/lstrlib.c +lua_mod_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/lua -DUSE_GRUB_LIB +lua_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For luacmd.mod. +luacmd_mod_SOURCES = lua/luacmd.c lua/lua.c +# Omitted lua/liolib.c and lua/loslib.c because they need to be ported to +# use the GRUB library. +luacmd_mod_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/lua \ + -DUSE_GRUB_LIB -DGRUB_COMMAND +luacmd_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For luagfx.mod. +luagfx_mod_SOURCES = commands/luagfx.c +luagfx_mod_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/lua +luagfx_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For luagrub.mod. +luagrub_mod_SOURCES = lib/luagrub.c +luagrub_mod_CFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/lua +luagrub_mod_LDFLAGS = $(COMMON_LDFLAGS) + === modified file 'gfxmenu/view.c' --- gfxmenu/view.c 2008-08-03 02:14:40 +0000 +++ gfxmenu/view.c 2008-08-04 17:10:55 +0000 @@ -35,11 +35,10 @@ #include #include #include - -/* Specifies a time (in ms) to delay so the user can read the message if a - default boot attempt fails and an attempt is made to fall back on - another entry. */ -#define FALLBACK_MESSAGE_DELAY 2000 +#include +#include +#include +#include typedef struct grub_gfxmenu_view_icon { @@ -78,6 +77,7 @@ grub_gfxmenu_box_t selected_item_box; grub_gfxmenu_box_t terminal_box; char *title_text; + lua_State *lua_state; char *progress_message_text; char *theme_path; /* Icon cache: linked list w/ dummy head node. */ @@ -149,6 +149,7 @@ view->selected_item_box = 0; view->terminal_box = 0; view->title_text = grub_strdup ("GRUB Boot Menu"); + view->lua_state = 0; view->progress_message_text = 0; view->theme_path = 0; view->icon_cache.class_name = 0; @@ -194,6 +195,8 @@ view->terminal_box->destroy (view->terminal_box); grub_free (view->terminal_font_name); grub_free (view->title_text); + if (view->lua_state) + lua_close (view->lua_state); grub_free (view->progress_message_text); grub_free (view->theme_path); free_icon_cache (view); @@ -295,6 +298,69 @@ } +/* Load the contents of the file located at PATH. Allocates a buffer and + stores it in *BUFP and returns the size. Returns -1 on error. */ +static grub_ssize_t +load_file (const char *path, char **bufp) +{ + *bufp = 0; + + grub_file_t f; + grub_errno = GRUB_ERR_NONE; + f = grub_file_open (path); + grub_errno = GRUB_ERR_NONE; + if (! f) + return -1; + + grub_size_t sz = grub_file_size (f); + char *buf = grub_malloc (sz); + if (! buf) + { + grub_file_close (f); + return -1; + } + grub_ssize_t n = grub_file_read (f, buf, sz); + if ((grub_size_t) n != sz) + { + grub_free (buf); + grub_file_close (f); + return -1; + } + grub_file_close (f); + *bufp = buf; + return n; +} + +/* Load the Lua script at PATH as a chunk of Lua code. This results in a + function being pushed on the Lua stack. */ +static int +grub_lua_load_file (lua_State *L, const char *path) +{ + /* Load the contents of the file. */ + char *buf; + grub_ssize_t n; + n = load_file (path, &buf); + if (n == -1) + return -1; + + /* Create a Lua function from it. */ + int err; + err = luaL_loadbuffer (L, buf, n, path); + grub_free (buf); + if (err) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Error loading Lua code"); + lua_pop (L, 1); /* Pop the error message. */ + return -1; + } + return 0; +} + +/* Error message buffer for debugging -- we should implement something + better, but this really helps debugging the theme loading by providing + some details on errors when things go wrong. */ +static char errbuf[400]; + /* Set the specified property NAME on the view to the given string VALUE. This function takes ownership of both NAME and VALUE, so the caller should pass pointers to new heap-allocated strings. */ @@ -372,6 +438,43 @@ view->title_text = value; value = 0; /* Prevent value from being freed below. */ } + else if (! grub_strcmp ("lua-script", name)) + { + grub_error_push (); + /* The 'lua-script' attribute specifies a Lua source file to load. */ + if (! view->lua_state) + { + view->lua_state = lua_open (); + if (! view->lua_state) + goto fail; + luaL_openlibs (view->lua_state); + grub_lua_load_grub_packages (view->lua_state); + } + + /* Load the file. */ + char *path; + path = grub_resolve_relative_path (theme_dir, value); + if (! path) + goto fail; + if (grub_lua_load_file (view->lua_state, path) != 0) + { + grub_strcat (errbuf, "lua script load failed. "); + grub_error (GRUB_ERR_FILE_READ_ERROR, "load script failed"); + grub_free (path); + goto fail; + } + grub_free (path); + + /* Execute the loaded chunk of Lua code. */ + int err; + err = lua_pcall (view->lua_state, 0, 0, 0); + if (err) + { + grub_strcat (errbuf, "script failed: "); + grub_strcat (errbuf, lua_tostring (view->lua_state, -1)); + goto fail; + } + } fail: grub_free (value); @@ -411,6 +514,13 @@ int pos; int len; + if (view->lua_state) + { + lua_close (view->lua_state); + view->lua_state = 0; + } + + errbuf[0] = '\0'; /* Clear the error messages. */ theme_dir = grub_get_dirname (theme_path); file = grub_file_open (theme_path); @@ -541,6 +651,7 @@ grub_free (buf); grub_file_close (file); grub_free (theme_dir); + return 1; } @@ -563,6 +674,36 @@ } } +static void +draw_lua_desktop (grub_gfxmenu_view_t view) +{ + lua_State *L = view->lua_state; + if (! L) + return; /* No Lua state, just return. */ + + lua_getglobal (L, "theme"); + if (! lua_isnoneornil (L, -1)) + { + lua_getfield (L, -1, "draw_desktop"); + if (! lua_isnoneornil (L, -1)) + { + lua_getglobal (L, "theme"); + if (! lua_isnoneornil (L, -1)) + { + /* We should check the return value of lua_pcall(), but we don't + have a good way to handle the error anyway, so for now we don't. */ + if (lua_pcall (L, 1, 0, 0) != 0) + { + /* Display the error message. */ + grub_strcpy (errbuf, lua_tostring (L, -1)); + } + } + } + } + + lua_settop (L, 0); /* Clear the stack. */ +} + static const char icon_extension[] = ".png"; static struct grub_video_bitmap * @@ -878,11 +1019,18 @@ { grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); draw_background (view); + draw_lua_desktop (view); draw_menu (view); draw_title (view); draw_status (view); draw_timeout (view); draw_message (view); + + /* Draw error messages if there are any. */ + if (errbuf[0]) + grub_video_draw_string (errbuf, + view->status_font, view->title_color, + 10,20); } static grub_err_t @@ -1023,7 +1171,6 @@ set_progress_message (view, s); grub_gfxmenu_view_draw (view); grub_video_swap_buffers (); - grub_millisleep (FALLBACK_MESSAGE_DELAY); } static void === modified file 'include/grub/i386/types.h' --- include/grub/i386/types.h 2007-07-21 22:32:33 +0000 +++ include/grub/i386/types.h 2008-08-01 15:27:27 +0000 @@ -25,6 +25,51 @@ /* The size of long. */ #define GRUB_TARGET_SIZEOF_LONG 4 +/* The native word size in bits. */ +#define __WORDSIZE 32 + +/* These assume 8-bit `char's, 16-bit `short int's, + and 32-bit `int's and `long int's. */ + +/* Number of bits in a `char'. */ +#define CHAR_BIT 8 + +/* Minimum and maximum values a `signed char' can hold. */ +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 + +/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ +#define UCHAR_MAX 255 + +/* Minimum and maximum values a `char' can hold. */ +#ifdef __CHAR_UNSIGNED__ +# define CHAR_MIN 0 +# define CHAR_MAX UCHAR_MAX +#else +# define CHAR_MIN SCHAR_MIN +# define CHAR_MAX SCHAR_MAX +#endif + +/* Minimum and maximum values for signed short int. */ +#define SHRT_MIN (-32768) +#define SHRT_MAX 32767 + +/* Maximum value for unsigned short int. (Minimum is 0.) */ +#define USHRT_MAX 65535 + +/* Mininum and maximum values for signed int. */ +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* Mininum and maximum values for signed long. */ +#if __WORDSIZE == 64 +# define LONG_MAX 9223372036854775807L +#else +# define LONG_MAX 2147483647L +#endif +#define LONG_MIN (-LONG_MAX - 1L) + /* i386 is little-endian. */ #undef GRUB_TARGET_WORDS_BIGENDIAN === added file 'include/grub/luagrub.h' --- include/grub/luagrub.h 1970-01-01 00:00:00 +0000 +++ include/grub/luagrub.h 2008-08-04 17:10:55 +0000 @@ -0,0 +1,27 @@ +/* luagrub.h - prototypes for GRUB Lua package functions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LUAGRUB_HEADER +#define GRUB_LUAGRUB_HEADER 1 + +#include + +int grub_lua_load_grub_packages (lua_State *L); + +#endif /* GRUB_LUAGRUB_HEADER */ === modified file 'include/grub/misc.h' --- include/grub/misc.h 2008-07-04 01:12:54 +0000 +++ include/grub/misc.h 2008-08-01 15:27:27 +0000 @@ -52,11 +52,14 @@ char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle); int EXPORT_FUNC(grub_iswordseparator) (int c); int EXPORT_FUNC(grub_isspace) (int c); +int EXPORT_FUNC(grub_iscntrl) (int c); int EXPORT_FUNC(grub_isprint) (int c); int EXPORT_FUNC(grub_isalpha) (int c); +int EXPORT_FUNC(grub_isalnum) (int c); int EXPORT_FUNC(grub_isgraph) (int c); int EXPORT_FUNC(grub_isdigit) (int c); int EXPORT_FUNC(grub_tolower) (int c); +long EXPORT_FUNC(grub_strtol) (const char *str, char **end, int base); unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); char *EXPORT_FUNC(grub_strdup) (const char *s); === modified file 'kern/misc.c' --- kern/misc.c 2008-07-04 18:03:26 +0000 +++ kern/misc.c 2008-08-01 15:27:27 +0000 @@ -358,6 +358,12 @@ } int +grub_iscntrl (int c) +{ + return (c >= 0x00 && c <= 0x1F) || c == 0x7F; +} + +int grub_isprint (int c) { return (c >= ' ' && c <= '~'); @@ -370,6 +376,12 @@ } int +grub_isalnum (int c) +{ + return grub_isalpha (c) || grub_isdigit (c); +} + +int grub_isdigit (int c) { return (c >= '0' && c <= '9'); @@ -390,6 +402,41 @@ return c; } +long +grub_strtol (const char *str, char **end, int base) +{ + int negative = 0; + + while (*str && grub_isspace (*str)) + str++; + + if (*str == '-') + { + negative = 1; + str++; + } + + unsigned long long magnitude; + magnitude = grub_strtoull (str, end, base); + if (negative) + { + if (magnitude > -((long long) LONG_MIN)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "negative overflow"); + return LONG_MIN; + } + return -((long long) magnitude); + } + else + { + if (magnitude > LONG_MAX) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "positive overflow"); + return LONG_MAX; + } + return (long) magnitude; + } +} unsigned long grub_strtoul (const char *str, char **end, int base) === added file 'lib/luagrub.c' --- lib/luagrub.c 1970-01-01 00:00:00 +0000 +++ lib/luagrub.c 2008-08-04 17:10:55 +0000 @@ -0,0 +1,185 @@ +/* luagrub.c - Lua GRUB package; provides access to GRUB from Lua. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Lua function: get_time_ms() : returns the time in milliseconds. */ +static int +l_sys_get_time_ms (lua_State *L) +{ + lua_pushinteger (L, grub_get_time_ms ()); + return 1; +} + + + +/* Lua function: input.getkey() : returns { ASCII char, scan code }. */ +static int +l_input_getkey (lua_State *L) +{ + int c = grub_getkey(); + lua_pushinteger (L, c & 0xFF); /* Push ASCII character code. */ + lua_pushinteger (L, (c >> 8) & 0xFF); /* Push the scan code. */ + return 2; +} + +/* Lua function: input.checkkey() : returns true if a key is waiting. */ +static int +l_input_checkkey (lua_State *L) +{ + lua_pushboolean (L, grub_checkkey() != -1); + return 1; +} + + + +/* Lua function: video.set_graphics_mode(). */ +static int +l_video_set_graphics_mode (lua_State *L) +{ + const char *doublebuf_str = grub_env_get ("doublebuffering"); + int doublebuf_flags = + (doublebuf_str && doublebuf_str[0] == 'n') + ? 0 + : GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + + const char *modestr = grub_env_get ("gfxmode"); + if (grub_video_setup_preferred_mode (modestr, doublebuf_flags, 640, 480) + != GRUB_ERR_NONE) + return luaL_error (L, "Error setting video mode: %s", grub_errmsg); + + return 0; +} + +/* Lua function: video.set_text_mode(). */ +static int +l_video_set_text_mode (lua_State *L) +{ + if (grub_video_restore () != GRUB_ERR_NONE) + return luaL_error (L, "Error setting text mode: %s", grub_errmsg); + return 0; +} + +/* Lua function: video.swap_buffers(). */ +static int +l_video_swap_buffers (lua_State *L) +{ + if (grub_video_swap_buffers () != GRUB_ERR_NONE) + return luaL_error (L, "Error swapping video buffers: %s", grub_errmsg); + return 0; +} + +static grub_video_color_t +check_grub_color (lua_State *L, int narg) +{ + /* Get the color components. */ + luaL_argcheck (L, lua_istable (L, narg), narg, "should be a color"); + lua_getfield (L, narg, "r"); + lua_getfield (L, narg, "g"); + lua_getfield (L, narg, "b"); + lua_getfield (L, narg, "a"); + grub_video_color_t color; + color = grub_video_map_rgba (luaL_checkint (L, -4), + luaL_checkint (L, -3), + luaL_checkint (L, -2), + luaL_optint (L, -1, 255)); + lua_pop (L, 4); + return color; +} + +/* Lua function: video.fill_rect(color, x, y, width, height). */ +static int +l_video_fill_rect (lua_State *L) +{ + grub_video_color_t color = check_grub_color (L, 1); + int x = luaL_checkint (L, 2); + int y = luaL_checkint (L, 3); + int w = luaL_checkint (L, 4); + int h = luaL_checkint (L, 5); + if (grub_video_fill_rect (color, x, y, w, h) != GRUB_ERR_NONE) + return luaL_error (L, "Error filling rectangle: %s", grub_errmsg); + return 0; +} + +/* Lua function: video.draw_string(text, font, color, x, y). */ +static int +l_video_draw_string (lua_State *L) +{ + grub_video_draw_string (luaL_checkstring (L, 1), + grub_font_get (luaL_checkstring (L, 2)), + check_grub_color (L, 3), + luaL_checkint (L, 4), + luaL_checkint (L, 5)); + return 0; +} + + +static const struct luaL_reg syslib[] = { + {"get_time_ms", l_sys_get_time_ms}, + {0, 0} +}; + +static const struct luaL_reg inputlib[] = { + {"getkey", l_input_getkey}, + {"checkkey", l_input_checkkey}, + {0, 0} +}; + +static const struct luaL_reg videolib[] = { + {"set_graphics_mode", l_video_set_graphics_mode}, + {"set_text_mode", l_video_set_text_mode}, + {"swap_buffers", l_video_swap_buffers}, + {"fill_rect", l_video_fill_rect}, + {"draw_string", l_video_draw_string}, + {0, 0} +}; + +int +grub_lua_load_grub_packages (lua_State *L) +{ + luaL_openlib(L, "sys", syslib, 0); + luaL_openlib(L, "input", inputlib, 0); + luaL_openlib(L, "video", videolib, 0); + return 3; /* 3 items returned on stack: the packages. */ +} + +GRUB_MOD_INIT (luagrub) +{ + (void) mod; /* To stop warning. */ +} + +GRUB_MOD_FINI (luagrub) +{ +} === added directory 'lua' === added file 'lua/Makefile' --- lua/Makefile 1970-01-01 00:00:00 +0000 +++ lua/Makefile 2008-08-01 15:19:23 +0000 @@ -0,0 +1,182 @@ +# makefile for building Lua +# see ../INSTALL for installation instructions +# see ../Makefile and luaconf.h for further customization + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +CC= gcc +CFLAGS= -O2 -Wall $(MYCFLAGS) +AR= ar rcu +RANLIB= ranlib +RM= rm -f +LIBS= -lm $(MYLIBS) + +MYCFLAGS= +MYLDFLAGS= +MYLIBS= + +# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= + +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +LUA_A= liblua.a +CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ + lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ + lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ + lstrlib.o loadlib.o linit.o + +LUA_T= lua +LUA_O= lua.o + +LUAC_T= luac +LUAC_O= luac.o print.o + +ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) + +default: $(PLAT) + +all: $(ALL_T) + +o: $(ALL_O) + +a: $(ALL_A) + +$(LUA_A): $(CORE_O) $(LIB_O) + $(AR) $@ $? + $(RANLIB) $@ + +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + +clean: + $(RM) $(ALL_T) $(ALL_O) + +depend: + @$(CC) $(CFLAGS) -MM l*.c print.c + +echo: + @echo "PLAT = $(PLAT)" + @echo "CC = $(CC)" + @echo "CFLAGS = $(CFLAGS)" + @echo "AR = $(AR)" + @echo "RANLIB = $(RANLIB)" + @echo "RM = $(RM)" + @echo "MYCFLAGS = $(MYCFLAGS)" + @echo "MYLDFLAGS = $(MYLDFLAGS)" + @echo "MYLIBS = $(MYLIBS)" + +# convenience targets for popular platforms + +none: + @echo "Please choose a platform:" + @echo " $(PLATS)" + +aix: + $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" + +ansi: + $(MAKE) all MYCFLAGS=-DLUA_ANSI + +bsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" + +freebsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" + +generic: + $(MAKE) all MYCFLAGS= + +linux: + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" + +macosx: + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" +# use this on Mac OS X 10.3- +# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX + +mingw: + $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ + "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ + "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe + $(MAKE) "LUAC_T=luac.exe" luac.exe + +posix: + $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX + +solaris: + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) default o a clean depend echo none + +# DO NOT DELETE + +lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ + lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \ + lundump.h lvm.h +lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h +lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h +lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ + ltable.h +ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h +ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ + llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \ + ltable.h lundump.h lvm.h +ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ + lstate.h ltm.h lzio.h +lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h +liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h +llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h +lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h +lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h +loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h +lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h +lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h +loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h +lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h +lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h +lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ + ltm.h lzio.h lstring.h lgc.h +lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h +ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h +ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h +ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ + lmem.h lstring.h lgc.h ltable.h +lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h +luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ + lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ + lundump.h +lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h +lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h +lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ + lzio.h +print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h lopcodes.h lundump.h + +# (end of Makefile) === added file 'lua/grublib.h' --- lua/grublib.h 1970-01-01 00:00:00 +0000 +++ lua/grublib.h 2008-08-01 15:27:27 +0000 @@ -0,0 +1,131 @@ +/* grublib.h - Define aliases to the GRUB library functions for Lua. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LUA_GRUBLIB_HEADER +#define GRUB_LUA_GRUBLIB_HEADER 1 + +#include +#include +#include + +#define isalpha grub_isalpha +#define isalnum grub_isalnum +#define isdigit grub_isdigit +#define isprint grub_isprint +#define isspace grub_isspace +#define iscntrl grub_iscntrl +#define tolower grub_tolower + +static __inline int islower(int c) +{ + return c >= 'a' && c <= 'z'; +} + +static __inline int isupper(int c) +{ + return c >= 'A' && c <= 'Z'; +} + +static __inline int toupper(int c) +{ + if (islower (c)) + return (c - 'a') + 'A'; + return c; +} + +static __inline int isxdigit(int c) +{ + return (isdigit (c) + || (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F')); +} + +static __inline int ispunct(int c) +{ + return isprint (c) && !isalnum (c); +} + + +#define memcmp grub_memcmp +#define strcmp grub_strcmp +#define strcoll grub_strcmp +#define strchr grub_strchr +#define strstr grub_strstr +#define strcspn grub_strcspn +#define strlen grub_strlen +#define strcpy grub_strcpy +#define strncpy grub_strncpy +#define strcat grub_strcat +#define strncat grub_strncat + +#define strtol grub_strtol +#define strtoul grub_strtoul +#define sprintf grub_sprintf +#define abs grub_abs + +#define malloc grub_malloc +#define realloc grub_realloc +#define free grub_free + +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +static __inline void exit (int status __attribute__ ((unused))) +{ + grub_exit (); +} + +static __inline void * +memchr (const char *s, int c, size_t n) +{ + while (n) + { + if (*s == c) + return (void *) s; + + n--; + s++; + } + return 0; +} + +static __inline char * +strpbrk (const char *s, const char *accept) +{ + char *p; + while (*s) + { + p = grub_strchr (accept, *s); + if (p) + return 0; + + s++; + } + return 0; +} + +static __inline size_t +strcspn (const char *s, const char *reject) +{ + size_t n = 0; + while (s[n] && ! grub_strchr (reject, s[n])) + n++; + return n; +} + +#endif /* ! GRUB_LUA_GRUBLIB_HEADER */ === added file 'lua/lapi.c' --- lua/lapi.c 1970-01-01 00:00:00 +0000 +++ lua/lapi.c 2008-08-03 02:57:07 +0000 @@ -0,0 +1,1080 @@ +/* +** $Id: lapi.c,v 2.55.1.3 2008/01/03 15:20:39 roberto Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define lapi_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) + +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) + +#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} + + + +static TValue *index2adr (lua_State *L, int idx) { + if (idx > 0) { + TValue *o = L->base + (idx - 1); + api_check(L, idx <= L->ci->top - L->base); + if (o >= L->top) return cast(TValue *, luaO_nilobject); + else return o; + } + else if (idx > LUA_REGISTRYINDEX) { + api_check(L, idx != 0 && -idx <= L->top - L->base); + return L->top + idx; + } + else switch (idx) { /* pseudo-indices */ + case LUA_REGISTRYINDEX: return registry(L); + case LUA_ENVIRONINDEX: { + Closure *func = curr_func(L); + sethvalue(L, &L->env, func->c.env); + return &L->env; + } + case LUA_GLOBALSINDEX: return gt(L); + default: { + Closure *func = curr_func(L); + idx = LUA_GLOBALSINDEX - idx; + return (idx <= func->c.nupvalues) + ? &func->c.upvalue[idx-1] + : cast(TValue *, luaO_nilobject); + } + } +} + + +static Table *getcurrenv (lua_State *L) { + if (L->ci == L->base_ci) /* no enclosing function? */ + return hvalue(gt(L)); /* use global table as environment */ + else { + Closure *func = curr_func(L); + return func->c.env; + } +} + + +void luaA_pushobject (lua_State *L, const TValue *o) { + setobj2s(L, L->top, o); + api_incr_top(L); +} + + +LUA_API int lua_checkstack (lua_State *L, int size) { + int res; + lua_lock(L); + if ((L->top - L->base + size) > LUAI_MAXCSTACK) + res = 0; /* stack overflow */ + else { + luaD_checkstack(L, size); + if (L->ci->top < L->top + size) + L->ci->top = L->top + size; + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to)); + api_check(from, to->ci->top - to->top >= n); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to, to->top++, from->top + i); + } + lua_unlock(to); +} + + +LUA_API void lua_setlevel (lua_State *from, lua_State *to) { + to->nCcalls = from->nCcalls; +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = luaE_newthread(L); + setthvalue(L, L->top, L1); + api_incr_top(L); + lua_unlock(L); + luai_userstatethread(L, L1); + return L1; +} + + + +/* +** basic stack manipulation +*/ + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top - L->base); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - L->base); + while (L->top < L->base + idx) + setnilvalue(L->top++); + L->top = L->base + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - L->base)); + L->top += idx+1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +LUA_API void lua_remove (lua_State *L, int idx) { + StkId p; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + while (++p < L->top) setobjs2s(L, p-1, p); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_insert (lua_State *L, int idx) { + StkId p; + StkId q; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); + setobjs2s(L, p, L->top); + lua_unlock(L); +} + + +LUA_API void lua_replace (lua_State *L, int idx) { + StkId o; + lua_lock(L); + /* explicit test for incompatible code */ + if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) + luaG_runerror(L, "no calling environment"); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + if (idx == LUA_ENVIRONINDEX) { + Closure *func = curr_func(L); + api_check(L, ttistable(L->top - 1)); + func->c.env = hvalue(L->top - 1); + luaC_barrier(L, func, L->top - 1); + } + else { + setobj(L, o, L->top - 1); + if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ + luaC_barrier(L, curr_func(L), L->top - 1); + } + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top, index2adr(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return iscfunction(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = index2adr(L, index1); + StkId o2 = index2adr(L, index2); + return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaO_rawequalObj(o1, o2); +} + + +LUA_API int lua_equal (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); + lua_unlock(L); + return i; +} + + +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaV_lessthan(L, o1, o2); + lua_unlock(L); + return i; +} + + + +LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) + return nvalue(o); + else + return 0; +} + + +LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + return res; + } + else + return 0; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + StkId o = index2adr(L, idx); + if (!ttisstring(o)) { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2adr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); +} + + +LUA_API size_t lua_objlen (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TSTRING: return tsvalue(o)->len; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + case LUA_TNUMBER: { + size_t l; + lua_lock(L); /* `luaV_tostring' may create a new string */ + l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); + lua_unlock(L); + return l; + } + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TUSERDATA: return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TFUNCTION: return clvalue(o); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { + lua_lock(L); + luaC_checkGC(L); + setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + Closure *cl; + lua_lock(L); + luaC_checkGC(L); + api_checknelems(L, n); + cl = luaF_newCclosure(L, n, getcurrenv(L)); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top+n); + setclvalue(L, L->top, cl); + lua_assert(iswhite(obj2gco(cl))); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_gettable(L, t, &key, L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); +} + + +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + lua_lock(L); + luaC_checkGC(L); + sethvalue(L, L->top, luaH_new(L, narray, nrec)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2adr(L, objindex); + switch (ttype(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttype(obj)]; + break; + } + if (mt == NULL) + res = 0; + else { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_getfenv (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + switch (ttype(o)) { + case LUA_TFUNCTION: + sethvalue(L, L->top, clvalue(o)->c.env); + break; + case LUA_TUSERDATA: + sethvalue(L, L->top, uvalue(o)->env); + break; + case LUA_TTHREAD: + setobj2s(L, L->top, gt(thvalue(o))); + break; + default: + setnilvalue(L->top); + break; + } + api_incr_top(L); + lua_unlock(L); +} + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + api_checknelems(L, 1); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_settable(L, t, &key, L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); + luaC_barriert(L, hvalue(t), L->top-1); + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); + luaC_barriert(L, hvalue(o), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2adr(L, objindex); + api_checkvalidindex(L, obj); + if (ttisnil(L->top - 1)) + mt = NULL; + else { + api_check(L, ttistable(L->top - 1)); + mt = hvalue(L->top - 1); + } + switch (ttype(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) + luaC_objbarriert(L, hvalue(obj), mt); + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) + luaC_objbarrier(L, rawuvalue(obj), mt); + break; + } + default: { + G(L)->mt[ttype(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; +} + + +LUA_API int lua_setfenv (lua_State *L, int idx) { + StkId o; + int res = 1; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + api_check(L, ttistable(L->top - 1)); + switch (ttype(o)) { + case LUA_TFUNCTION: + clvalue(o)->c.env = hvalue(L->top - 1); + break; + case LUA_TUSERDATA: + uvalue(o)->env = hvalue(L->top - 1); + break; + case LUA_TTHREAD: + sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); + break; + default: + res = 0; + break; + } + if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + L->top--; + lua_unlock(L); + return res; +} + + +/* +** `load' and `call' functions (run Lua code) +*/ + + +#define adjustresults(L,nres) \ + { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) + + +LUA_API void lua_call (lua_State *L, int nargs, int nresults) { + StkId func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + func = L->top - (nargs+1); + luaD_call(L, func, nresults); + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2adr(L, errfunc); + api_checkvalidindex(L, o); + func = savestack(L, o); + } + c.func = L->top - (nargs+1); /* function to be called */ + c.nresults = nresults; + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +/* +** Execute a protected C call. +*/ +struct CCallS { /* data to `f_Ccall' */ + lua_CFunction func; + void *ud; +}; + + +static void f_Ccall (lua_State *L, void *ud) { + struct CCallS *c = cast(struct CCallS *, ud); + Closure *cl; + cl = luaF_newCclosure(L, 0, getcurrenv(L)); + cl->c.f = c->func; + setclvalue(L, L->top, cl); /* push function */ + api_incr_top(L); + setpvalue(L->top, c->ud); /* push only argument */ + api_incr_top(L); + luaD_call(L, L->top - 2, 0); +} + + +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { + struct CCallS c; + int status; + lua_lock(L); + c.func = func; + c.ud = ud; + status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname); + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ + +LUA_API int lua_gc (lua_State *L, int what, int data) { + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) { + case LUA_GCSTOP: { + g->GCthreshold = MAX_LUMEM; + break; + } + case LUA_GCRESTART: { + g->GCthreshold = g->totalbytes; + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(g->totalbytes >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(g->totalbytes & 0x3ff); + break; + } + case LUA_GCSTEP: { + lu_mem a = (cast(lu_mem, data) << 10); + if (a <= g->totalbytes) + g->GCthreshold = g->totalbytes - a; + else + g->GCthreshold = 0; + while (g->GCthreshold <= g->totalbytes) + luaC_step(L); + if (g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ + break; + } + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + default: res = -1; /* invalid option */ + } + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + lua_unlock(L); + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) { + luaC_checkGC(L); + luaV_concat(L, n, cast_int(L->top - L->base) - 1); + L->top -= (n-1); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, getcurrenv(L)); + setuvalue(L, L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; +} + + + + +static const char *aux_upvalue (StkId fi, int n, TValue **val) { + Closure *f; + if (!ttisfunction(fi)) return NULL; + f = clvalue(fi); + if (f->c.isC) { + if (!(1 <= n && n <= f->c.nupvalues)) return NULL; + *val = &f->c.upvalue[n-1]; + return ""; + } + else { + Proto *p = f->l.p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->l.upvals[n-1]->v; + return getstr(p->upvalues[n-1]); + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + lua_lock(L); + name = aux_upvalue(index2adr(L, funcindex), n, &val); + if (name) { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + StkId fi; + lua_lock(L); + fi = index2adr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val); + if (name) { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, clvalue(fi), L->top); + } + lua_unlock(L); + return name; +} + === added file 'lua/lapi.h' --- lua/lapi.h 1970-01-01 00:00:00 +0000 +++ lua/lapi.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,16 @@ +/* +** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "lobject.h" + + +LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); + +#endif === added file 'lua/lauxlib.c' --- lua/lauxlib.c 1970-01-01 00:00:00 +0000 +++ lua/lauxlib.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,679 @@ +/* +** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#include +#include +#include + +#else +#include +#include +#include +#endif /* USE_GRUB_LIB */ + + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" + + +#define FREELIST_REF 0 /* free list of references */ + + +/* convert a stack index to positive */ +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ + lua_gettop(L) + (i) + 1) + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + + +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + narg, ar.name, extramsg); +} + + +LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + + +static void tag_error (lua_State *L, int narg, int tag) { + luaL_typerror(L, narg, lua_typename(L, tag)); +} + + +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ +} + + +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + +/* }====================================================== */ + + +LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, narg, def) : + luaL_checkstring(L, narg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, + lua_pushfstring(L, "invalid option " LUA_QS, name)); +} + + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ + if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + } + luaL_typerror(L, ud, tname); /* else error */ + return NULL; /* to avoid warnings */ +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { + if (!lua_checkstack(L, space)) + luaL_error(L, "stack overflow (%s)", mes); +} + + +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { + const char *s = lua_tolstring(L, narg, len); + if (!s) tag_error(L, narg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, narg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { + lua_Number d = lua_tonumber(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, narg, def); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { + lua_Integer d = lua_tointeger(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, narg, def); +} + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = abs_index(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l) { + luaI_openlib(L, libname, l, 0); +} + + +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l->name; l++) size++; + return size; +} + + +LUALIB_API void luaI_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + if (libname) { + int size = libsize(l); + /* check whether lib already exists */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); + lua_getfield(L, -1, libname); /* get _LOADED[libname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, libname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ + lua_insert(L, -(nup+1)); /* move library table to below upvalues */ + } + for (; l->name; l++) { + int i; + for (i=0; ifunc, nup); + lua_setfield(L, -(nup+2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + + +/* +** {====================================================== +** getn-setn: size for arrays +** ======================================================= +*/ + +#if defined(LUA_COMPAT_GETN) + +static int checkint (lua_State *L, int topop) { + int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; + lua_pop(L, topop); + return n; +} + + +static void getsizes (lua_State *L) { + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); + if (lua_isnil(L, -1)) { /* no `size' table? */ + lua_pop(L, 1); /* remove nil */ + lua_newtable(L); /* create it */ + lua_pushvalue(L, -1); /* `size' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ + } +} + + +LUALIB_API void luaL_setn (lua_State *L, int t, int n) { + t = abs_index(L, t); + lua_pushliteral(L, "n"); + lua_rawget(L, t); + if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ + lua_pushliteral(L, "n"); /* use it */ + lua_pushinteger(L, n); + lua_rawset(L, t); + } + else { /* use `sizes' */ + getsizes(L); + lua_pushvalue(L, t); + lua_pushinteger(L, n); + lua_rawset(L, -3); /* sizes[t] = n */ + lua_pop(L, 1); /* remove `sizes' */ + } +} + + +LUALIB_API int luaL_getn (lua_State *L, int t) { + int n; + t = abs_index(L, t); + lua_pushliteral(L, "n"); /* try t.n */ + lua_rawget(L, t); + if ((n = checkint(L, 1)) >= 0) return n; + getsizes(L); /* else try sizes[t] */ + lua_pushvalue(L, t); + lua_rawget(L, -2); + if ((n = checkint(L, 2)) >= 0) return n; + return (int)lua_objlen(L, t); +} + +#endif + +/* }====================================================== */ + + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +LUALIB_API const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { + const char *e; + lua_pushvalue(L, idx); + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; +} + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + +#define bufflen(B) ((B)->p - (B)->buffer) +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) + +#define LIMIT (LUA_MINSTACK/2) + + +static int emptybuffer (luaL_Buffer *B) { + size_t l = bufflen(B); + if (l == 0) return 0; /* put nothing on stack */ + else { + lua_pushlstring(B->L, B->buffer, l); + B->p = B->buffer; + B->lvl++; + return 1; + } +} + + +static void adjuststack (luaL_Buffer *B) { + if (B->lvl > 1) { + lua_State *L = B->L; + int toget = 1; /* number of levels to concat */ + size_t toplen = lua_strlen(L, -1); + do { + size_t l = lua_strlen(L, -(toget+1)); + if (B->lvl - toget + 1 >= LIMIT || toplen > l) { + toplen += l; + toget++; + } + else break; + } while (toget < B->lvl); + lua_concat(L, toget); + B->lvl = B->lvl - toget + 1; + } +} + + +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { + if (emptybuffer(B)) + adjuststack(B); + return B->buffer; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + while (l--) + luaL_addchar(B, *s++); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + emptybuffer(B); + lua_concat(B->L, B->lvl); + B->lvl = 1; +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t vl; + const char *s = lua_tolstring(L, -1, &vl); + if (vl <= bufffree(B)) { /* fit into buffer? */ + memcpy(B->p, s, vl); /* put it there */ + B->p += vl; + lua_pop(L, 1); /* remove from stack */ + } + else { + if (emptybuffer(B)) + lua_insert(L, -2); /* put buffer before new value */ + B->lvl++; /* add new value into B stack */ + adjuststack(B); + } +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->p = B->buffer; + B->lvl = 0; +} + +/* }====================================================== */ + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + t = abs_index(L, t); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ + } + else { /* no free elements */ + ref = (int)lua_objlen(L, t); + ref++; /* create new reference */ + } + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = abs_index(L, t); + lua_rawgeti(L, t, FREELIST_REF); + lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ + } +} + + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int extraline; + grub_file_t f; + char buff[LUAL_BUFFERSIZE]; +} LoadF; + + +#define EOF (-1) + +static int grub_file_error_flag = 0; + +static int grub_getc(grub_file_t f) +{ + char c; + if (grub_file_read (f, &c, 1) != 1) + { + grub_file_error_flag = 1; + return EOF; + } + grub_file_error_flag = 0; + return c; +} + +static int grub_ferror(void) +{ + return grub_file_error_flag; +} + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; + if (lf->extraline) { + lf->extraline = 0; + *size = 1; + return "\n"; + } + *size = grub_file_read(lf->f, lf->buff, sizeof(lf->buff)); + return (*size > 0) ? lf->buff : NULL; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + const char *serr = grub_errmsg; + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + +LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + lf.extraline = 0; + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + grub_error(GRUB_ERR_UNKNOWN_DEVICE, "stdin not supported"); + return errfile(L, "open stdin (not supported)", fnameindex); + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = grub_buffile_open(filename, -1); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + c = grub_getc(lf.f); + if (c == '#') { /* Unix exec. file? */ + lf.extraline = 1; + while ((c = grub_getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ + if (c == '\n') c = grub_getc(lf.f); + } + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + grub_file_seek(lf.f, 0); + /* skip eventual `#!...' */ + while ((c = grub_getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; + lf.extraline = 0; + } + grub_file_seek(lf.f, 0); + status = lua_load(L, getF, &lf, lua_tostring(L, -1)); + readstatus = grub_ferror(); + if (filename) grub_file_close(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, + const char *name) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name); +} + + +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + + + +/* }====================================================== */ + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; + (void)osize; + if (nsize == 0) { + grub_free(ptr); + return NULL; + } + else + return grub_realloc(ptr, nsize); +} + + +static int panic (lua_State *L) { + (void)L; /* to avoid warnings */ + grub_printf("PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (L) lua_atpanic(L, &panic); + return L; +} + === added file 'lua/lauxlib.h' --- lua/lauxlib.h 1970-01-01 00:00:00 +0000 +++ lua/lauxlib.h 2008-08-01 15:27:27 +0000 @@ -0,0 +1,176 @@ +/* +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#include "lua.h" + + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + === added file 'lua/lbaselib.c' --- lua/lbaselib.c 1970-01-01 00:00:00 +0000 +++ lua/lbaselib.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,656 @@ +/* +** $Id: lbaselib.c,v 1.191.1.4 2008/01/20 13:53:22 roberto Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#include +#define PRINT(s) fputs(s, stdout) +#else +#define PRINT(s) grub_printf("%s", s) +#endif /* ! USE_GRUB_LIB */ + +#define lbaselib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + + +/* +** If your system does not support `stdout', you can just remove this function. +** If you need, you can define your own `print' function, following this +** model but changing `fputs' to put the strings at a proper place +** (a console window or a log file, for instance). +*/ +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, LUA_QL("tostring") " must return a string to " + LUA_QL("print")); + if (i>1) PRINT("\t"); + PRINT(s); + lua_pop(L, 1); /* pop result */ + } + PRINT("\n"); + return 0; +} + + +static int luaB_tonumber (lua_State *L) { + int base = luaL_optint(L, 2, 10); + if (base == 10) { /* standard conversion */ + luaL_checkany(L, 1); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } + } + else { + const char *s1 = luaL_checkstring(L, 1); + char *s2; + unsigned long n; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) { /* at least one valid digit? */ + while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ + if (*s2 == '\0') { /* no invalid trailing characters? */ + lua_pushnumber(L, (lua_Number)n); + return 1; + } + } + } + lua_pushnil(L); /* else not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static void getfunc (lua_State *L, int opt) { + if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); + else { + lua_Debug ar; + int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); + luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + if (lua_getstack(L, level, &ar) == 0) + luaL_argerror(L, 1, "invalid level"); + lua_getinfo(L, "f", &ar); + if (lua_isnil(L, -1)) + luaL_error(L, "no function environment for tail call at level %d", + level); + } +} + + +static int luaB_getfenv (lua_State *L) { + getfunc(L, 1); + if (lua_iscfunction(L, -1)) /* is a C function? */ + lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ + else + lua_getfenv(L, -1); + return 1; +} + + +static int luaB_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + getfunc(L, 0); + lua_pushvalue(L, 2); + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { + /* change environment of current thread */ + lua_pushthread(L); + lua_insert(L, -2); + lua_setfenv(L, -2); + return 0; + } + else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) + luaL_error(L, + LUA_QL("setfenv") " cannot change environment of given object"); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_gcinfo (lua_State *L) { + lua_pushinteger(L, lua_getgccount(L)); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; + int o = luaL_checkoption(L, 1, "collect", opts); + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, optsnum[o], ex); + switch (optsnum[o]) { + case LUA_GCCOUNT: { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushnumber(L, res); + return 1; + } + } +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + return 3; +} + + +static int ipairsaux (lua_State *L) { + int i = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 0 : 2; +} + + +static int luaB_ipairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushinteger(L, 0); /* and initial value */ + return 3; +} + + +static int load_aux (lua_State *L, int status) { + if (status == 0) /* OK? */ + return 1; + else { + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + + +static int luaB_loadstring (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *chunkname = luaL_optstring(L, 2, s); + return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + return load_aux(L, luaL_loadfile(L, fname)); +} + + +/* +** Reader for generic `load' function: `lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)ud; /* to avoid warnings */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + *size = 0; + return NULL; + } + else if (lua_isstring(L, -1)) { + lua_replace(L, 3); /* save string in a reserved stack slot */ + return lua_tolstring(L, 3, size); + } + else luaL_error(L, "reader function must return a string"); + return NULL; /* to avoid warnings */ +} + + +static int luaB_load (lua_State *L) { + int status; + const char *cname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ + status = lua_load(L, generic_reader, NULL, cname); + return load_aux(L, status); +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + int n = lua_gettop(L); + if (luaL_loadfile(L, fname) != 0) lua_error(L); + lua_call(L, 0, LUA_MULTRET); + return lua_gettop(L) - n; +} + + +static int luaB_assert (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + + +static int luaB_unpack (lua_State *L) { + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + n = e - i + 1; /* number of elements */ + if (n <= 0) return 0; /* empty range */ + luaL_checkstack(L, n, "table too big to unpack"); + for (; i<=e; i++) /* push arg[i...e] */ + lua_rawgeti(L, 1, i); + return n; +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + int i = luaL_checkint(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); + lua_pushboolean(L, (status == 0)); + lua_insert(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_xpcall (lua_State *L) { + int status; + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_insert(L, 1); /* put error function under function to be called */ + status = lua_pcall(L, 0, LUA_MULTRET, 1); + lua_pushboolean(L, (status == 0)); + lua_replace(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ + return 1; /* use its value */ + switch (lua_type(L, 1)) { + case LUA_TNUMBER: + lua_pushstring(L, lua_tostring(L, 1)); + break; + case LUA_TSTRING: + lua_pushvalue(L, 1); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); + break; + } + return 1; +} + + +static int luaB_newproxy (lua_State *L) { + lua_settop(L, 1); + lua_newuserdata(L, 0); /* create proxy */ + if (lua_toboolean(L, 1) == 0) + return 1; /* no metatable */ + else if (lua_isboolean(L, 1)) { + lua_newtable(L); /* create a new metatable `m' ... */ + lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ + lua_pushboolean(L, 1); + lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ + } + else { + int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ + if (lua_getmetatable(L, 1)) { + lua_rawget(L, lua_upvalueindex(1)); + validproxy = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + } + luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); + lua_getmetatable(L, 1); /* metatable is valid; get it */ + } + lua_setmetatable(L, 2); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"gcinfo", luaB_gcinfo}, + {"getfenv", luaB_getfenv}, + {"getmetatable", luaB_getmetatable}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, + {"loadstring", luaB_loadstring}, + {"next", luaB_next}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"rawequal", luaB_rawequal}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setfenv", luaB_setfenv}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"unpack", luaB_unpack}, + {"xpcall", luaB_xpcall}, + {NULL, NULL} +}; + + +/* +** {====================================================== +** Coroutine library +** ======================================================= +*/ + +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 + +static const char *const statnames[] = + {"running", "suspended", "normal", "dead"}; + +static int costatus (lua_State *L, lua_State *co) { + if (L == co) return CO_RUN; + switch (lua_status(co)) { + case LUA_YIELD: + return CO_SUS; + case 0: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + return CO_NOR; /* it is running */ + else if (lua_gettop(co) == 0) + return CO_DEAD; + else + return CO_SUS; /* initial state */ + } + default: /* some error occured */ + return CO_DEAD; + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + lua_pushstring(L, statnames[costatus(L, co)]); + return 1; +} + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status = costatus(L, co); + if (!lua_checkstack(co, narg)) + luaL_error(L, "too many arguments to resume"); + if (status != CO_SUS) { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + lua_setlevel(L, co); + status = lua_resume(co, narg); + if (status == 0 || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL = lua_newthread(L); + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, + "Lua function expected"); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_corunning (lua_State *L) { + if (lua_pushthread(L)) + lua_pushnil(L); /* main thread is not a coroutine */ + return 1; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL} +}; + +/* }====================================================== */ + + +static void auxopen (lua_State *L, const char *name, + lua_CFunction f, lua_CFunction u) { + lua_pushcfunction(L, u); + lua_pushcclosure(L, f, 1); + lua_setfield(L, -2, name); +} + + +static void base_open (lua_State *L) { + /* set global _G */ + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "_G"); + /* open lib into global table */ + luaL_register(L, "_G", base_funcs); + lua_pushliteral(L, LUA_VERSION); + lua_setglobal(L, "_VERSION"); /* set global _VERSION */ + /* `ipairs' and `pairs' need auxliliary functions as upvalues */ + auxopen(L, "ipairs", luaB_ipairs, ipairsaux); + auxopen(L, "pairs", luaB_pairs, luaB_next); + /* `newproxy' needs a weaktable as upvalue */ + lua_createtable(L, 0, 1); /* new table `w' */ + lua_pushvalue(L, -1); /* `w' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ + lua_pushcclosure(L, luaB_newproxy, 1); + lua_setglobal(L, "newproxy"); /* set global `newproxy' */ +} + + +LUALIB_API int luaopen_base (lua_State *L) { + base_open(L); + luaL_register(L, LUA_COLIBNAME, co_funcs); + return 2; +} + === added file 'lua/lcode.c' --- lua/lcode.c 1970-01-01 00:00:00 +0000 +++ lua/lcode.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,841 @@ +/* +** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lcode_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "ltable.h" + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int isnumeral(expdesc *e) { + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); +} + + +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + if (fs->pc == 0) { /* function start? */ + if (from >= fs->nactvar) + return; /* positions are already clean */ + } + else { + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pto = GETARG_B(*previous); + if (pfrom <= from && from <= pto+1) { /* can connect both? */ + if (from+n-1 > pto) + SETARG_B(*previous, from+n-1); + return; + } + } + } + } + luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ +} + + +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +void luaK_ret (FuncState *fs, int first, int nret) { + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** returns current `pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** check whether list has any jump that do not produce a value +** (or produce an inverted value) +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + + return 1; +} + + +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) + luaK_patchtohere(fs, list); + else { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } +} + + +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } +} + + +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +static void freereg (FuncState *fs, int reg) { + if (!ISK(reg) && reg >= fs->nactvar) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.s.info); +} + + +static int addk (FuncState *fs, TValue *k, TValue *v) { + lua_State *L = fs->L; + TValue *idx = luaH_set(L, fs->h, k); + Proto *f = fs->f; + int oldsize = f->sizek; + if (ttisnumber(idx)) { + lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); + return cast_int(nvalue(idx)); + } + else { /* constant not found; create a new entry */ + setnvalue(idx, cast_num(fs->nk)); + luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[fs->nk], v); + luaC_barrier(L, f, v); + return fs->nk++; + } +} + + +int luaK_stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->L, &o, s); + return addk(fs, &o, &o); +} + + +int luaK_numberK (FuncState *fs, lua_Number r) { + TValue o; + setnvalue(&o, r); + return addk(fs, &o, &o); +} + + +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); +} + + +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->L, &k, fs->h); + return addk(fs, &k, &v); +} + + +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults+1); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), nresults+1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.s.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } +} + + +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { + e->k = VNONRELOC; + break; + } + case VUPVAL: { + e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + case VGLOBAL: { + e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + freereg(fs, e->u.s.aux); + freereg(fs, e->u.s.info); + e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +static int code_label (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); + break; + } + case VKNUM: { + luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: { + if (reg != e->u.s.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); + break; + } + default: { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg-1); + } +} + + +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { + if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ + if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.s.info); /* put value on it */ + return e->u.s.info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->u.s.info; +} + + +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { + case VKNUM: + case VTRUE: + case VFALSE: + case VNIL: { + if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ + e->u.s.info = (e->k == VNIL) ? nilK(fs) : + (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : + boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.s.info); + } + else break; + } + case VK: { + if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ + return RKASK(e->u.s.info); + else break; + } + default: break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); +} + + +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.s.info); + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); + break; + } + case VGLOBAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); + break; + } + case VINDEXED: { + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); + break; + } + default: { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); +} + + +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int func; + luaK_exp2anyreg(fs, e); + freeexp(fs, e); + func = fs->freereg; + luaK_reserveregs(fs, 2); + luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); + freeexp(fs, key); + e->u.s.info = func; + e->k = VNONRELOC; +} + + +static void invertjump (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.s.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); +} + + +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VK: case VKNUM: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + case VFALSE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + invertjump(fs, e); + pc = e->u.s.info; + break; + } + default: { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; +} + + +static void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + case VTRUE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + pc = e->u.s.info; + break; + } + default: { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; +} + + +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; + break; + } + case VK: case VKNUM: case VTRUE: { + e->k = VFALSE; + break; + } + case VJMP: { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + default: { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); + removevalues(fs, e->t); +} + + +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + t->u.s.aux = luaK_exp2RK(fs, k); + t->k = VINDEXED; +} + + +static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { + lua_Number v1, v2, r; + if (!isnumeral(e1) || !isnumeral(e2)) return 0; + v1 = e1->u.nval; + v2 = e2->u.nval; + switch (op) { + case OP_ADD: r = luai_numadd(v1, v2); break; + case OP_SUB: r = luai_numsub(v1, v2); break; + case OP_MUL: r = luai_nummul(v1, v2); break; + case OP_DIV: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_numdiv(v1, v2); break; + case OP_MOD: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_nummod(v1, v2); break; + case OP_POW: r = luai_numpow(v1, v2); break; + case OP_UNM: r = luai_numunm(v1); break; + case OP_LEN: return 0; /* no constant folding for 'len' */ + default: lua_assert(0); r = 0; break; + } + if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ + e1->u.nval = r; + return 1; +} + + +static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { + if (constfolding(op, e1, e2)) + return; + else { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) { + freeexp(fs, e1); + freeexp(fs, e2); + } + else { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; + } +} + + +static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, + expdesc *e2) { + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + if (cond == 0 && op != OP_EQ) { + int temp; /* exchange args to replace by `<' or `<=' */ + temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ + cond = 1; + } + e1->u.s.info = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; +} + + +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { + expdesc e2; + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; + switch (op) { + case OPR_MINUS: { + if (!isnumeral(e)) + luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ + codearith(fs, OP_UNM, e, &e2); + break; + } + case OPR_NOT: codenot(fs, e); break; + case OPR_LEN: { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2); + break; + } + default: lua_assert(0); + } +} + + +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + if (!isnumeral(v)) luaK_exp2RK(fs, v); + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.s.info); + e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; + } + else { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2); + } + break; + } + case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; + case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; + case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; + case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; + case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; + case OPR_POW: codearith(fs, OP_POW, e1, e2); break; + case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; + case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; + case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; + case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; + case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; + case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; + default: lua_assert(0); + } +} + + +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +static int luaK_code (FuncState *fs, Instruction i, int line) { + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "code size overflow"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "code size overflow"); + f->lineinfo[fs->pc] = line; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); +} + + +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + luaK_code(fs, cast(Instruction, c), fs->ls->lastline); + } + fs->freereg = base + 1; /* free registers with list values */ +} + === added file 'lua/lcode.h' --- lua/lcode.h 1970-01-01 00:00:00 +0000 +++ lua/lcode.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,76 @@ +/* +** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, + OPR_CONCAT, + OPR_NE, OPR_EQ, + OPR_LT, OPR_LE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); + + +#endif === added file 'lua/ldblib.c' --- lua/ldblib.c 1970-01-01 00:00:00 +0000 +++ lua/ldblib.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,399 @@ +/* +** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#ifdef USE_GRUB_LIB +#include /* for grub_cmdline_get() */ +#else /* ! USE_GRUB_LIB */ +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define ldblib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + lua_settop(L, 2); + lua_pushboolean(L, lua_setmetatable(L, 1)); + return 1; +} + + +static int db_getfenv (lua_State *L) { + lua_getfenv(L, 1); + return 1; +} + + +static int db_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + lua_settop(L, 2); + if (lua_setfenv(L, 1) == 0) + luaL_error(L, LUA_QL("setfenv") + " cannot change environment of given object"); + return 1; +} + + +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, i); +} + + +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, i); +} + + +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } +} + + +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSu"); + if (lua_isnumber(L, arg+1)) { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg+1)) { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg+1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); + if (name) { + lua_xmove(L1, L, 1); + lua_pushstring(L, name); + lua_pushvalue(L, -2); + return 2; + } + else { + lua_pushnil(L); + return 1; + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); + return 1; +} + + +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + + +static const char KEY_HOOK = 'h'; + + +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail return"}; + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } +} + + +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static void gethooktable (lua_State *L) { + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); + } + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_pushvalue(L, arg+1); + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + if (grub_cmdline_get("lua_debug> ", buffer, sizeof(buffer), 0, 1) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) { + grub_printf("%s\n", lua_tostring(L, -1)); + } + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int db_errorfb (lua_State *L) { + int level; + int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (lua_isnumber(L, arg+2)) { + level = (int)lua_tointeger(L, arg+2); + lua_pop(L, 1); + } + else + level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ + if (lua_gettop(L) == arg) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ + else lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L1, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L1, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L) - arg); + } + lua_concat(L, lua_gettop(L) - arg); + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getfenv", db_getfenv}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"setfenv", db_setfenv}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_errorfb}, + {NULL, NULL} +}; + + +LUALIB_API int luaopen_debug (lua_State *L) { + luaL_register(L, LUA_DBLIBNAME, dblib); + return 1; +} + === added file 'lua/ldebug.c' --- lua/ldebug.c 1970-01-01 00:00:00 +0000 +++ lua/ldebug.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,624 @@ +/* +** $Id: ldebug.c,v 2.29.1.3 2007/12/28 15:32:23 roberto Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + + +#define ldebug_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); + + +static int currentpc (lua_State *L, CallInfo *ci) { + if (!isLua(ci)) return -1; /* function is not a Lua function? */ + if (ci == L->ci) + ci->savedpc = L->savedpc; + return pcRel(ci->savedpc, ci_func(ci)->l.p); +} + + +static int currentline (lua_State *L, CallInfo *ci) { + int pc = currentpc(L, ci); + if (pc < 0) + return -1; /* only active lua functions have current-line information */ + else + return getline(ci_func(ci)->l.p, pc); +} + + +/* +** this function can be called asynchronous (e.g. during a signal) +*/ +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + lua_lock(L); + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { + level--; + if (f_isLua(ci)) /* Lua function? */ + level -= ci->tailcalls; /* skip lost tail calls */ + } + if (level == 0 && ci > L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = cast_int(ci - L->base_ci); + } + else if (level < 0) { /* level is of a lost tail call? */ + status = 1; + ar->i_ci = 0; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static Proto *getluaproto (CallInfo *ci) { + return (isLua(ci) ? ci_func(ci)->l.p : NULL); +} + + +static const char *findlocal (lua_State *L, CallInfo *ci, int n) { + const char *name; + Proto *fp = getluaproto(ci); + if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) + return name; /* is a local variable in a Lua function */ + else { + StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; + if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + return "(*temporary)"; + else + return NULL; + } +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + luaA_pushobject(L, ci->base + (n - 1)); + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + setobjs2s(L, ci->base + (n - 1), L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (cl->c.isC) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + ar->source = getstr(cl->l.p->source); + ar->linedefined = cl->l.p->linedefined; + ar->lastlinedefined = cl->l.p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static void info_tailcall (lua_Debug *ar) { + ar->name = ar->namewhat = ""; + ar->what = "tail"; + ar->lastlinedefined = ar->linedefined = ar->currentline = -1; + ar->source = "=(tail call)"; + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); + ar->nups = 0; +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (f == NULL || f->c.isC) { + setnilvalue(L->top); + } + else { + Table *t = luaH_new(L, 0, 0); + int *lineinfo = f->l.p->lineinfo; + int i; + for (i=0; il.p->sizelineinfo; i++) + setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); + sethvalue(L, L->top, t); + } + incr_top(L); +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + if (f == NULL) { + info_tailcall(ar); + return status; + } + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci) ? currentline(L, ci) : -1; + break; + } + case 'u': { + ar->nups = f->c.nupvalues; + break; + } + case 'n': { + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *f = NULL; + CallInfo *ci = NULL; + lua_lock(L); + if (*what == '>') { + StkId func = L->top - 1; + luai_apicheck(L, ttisfunction(func)); + what++; /* skip the '>' */ + f = clvalue(func); + L->top--; /* pop function */ + } + else if (ar->i_ci != 0) { /* no tail call? */ + ci = L->base_ci + ar->i_ci; + lua_assert(ttisfunction(ci->func)); + f = clvalue(ci->func); + } + status = auxgetinfo(L, what, ar, f, ci); + if (strchr(what, 'f')) { + if (f == NULL) setnilvalue(L->top); + else setclvalue(L, L->top, f); + incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, f); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution and code checker +** ======================================================= +*/ + +#define check(x) if (!(x)) return 0; + +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) + +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) + + + +static int precheck (const Proto *pt) { + check(pt->maxstacksize <= MAXSTACK); + lua_assert(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); + lua_assert(!(pt->is_vararg & VARARG_NEEDSARG) || + (pt->is_vararg & VARARG_HASARG)); + check(pt->sizeupvalues <= pt->nups); + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); + check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); + return 1; +} + + +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) + +int luaG_checkopenop (Instruction i) { + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + case OP_RETURN: + case OP_SETLIST: { + check(GETARG_B(i) == 0); + return 1; + } + default: return 0; /* invalid instruction after an open call */ + } +} + + +static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { + switch (mode) { + case OpArgN: check(r == 0); break; + case OpArgU: break; + case OpArgR: checkreg(pt, r); break; + case OpArgK: + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); + break; + } + return 1; +} + + +static Instruction symbexec (const Proto *pt, int lastpc, int reg) { + int pc; + int last; /* stores position of last instruction that changed `reg' */ + last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ + check(precheck(pt)); + for (pc = 0; pc < lastpc; pc++) { + Instruction i = pt->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int b = 0; + int c = 0; + check(op < NUM_OPCODES); + checkreg(pt, a); + switch (getOpMode(op)) { + case iABC: { + b = GETARG_B(i); + c = GETARG_C(i); + check(checkArgMode(pt, b, getBMode(op))); + check(checkArgMode(pt, c, getCMode(op))); + break; + } + case iABx: { + b = GETARG_Bx(i); + if (getBMode(op) == OpArgK) check(b < pt->sizek); + break; + } + case iAsBx: { + b = GETARG_sBx(i); + if (getBMode(op) == OpArgR) { + int dest = pc+1+b; + check(0 <= dest && dest < pt->sizecode); + if (dest > 0) { + /* cannot jump to a setlist count */ + Instruction d = pt->code[dest-1]; + check(!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)); + } + } + break; + } + } + if (testAMode(op)) { + if (a == reg) last = pc; /* change register `a' */ + } + if (testTMode(op)) { + check(pc+2 < pt->sizecode); /* check skip */ + check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); + } + switch (op) { + case OP_LOADBOOL: { + check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ + break; + } + case OP_LOADNIL: { + if (a <= reg && reg <= b) + last = pc; /* set registers from `a' to `b' */ + break; + } + case OP_GETUPVAL: + case OP_SETUPVAL: { + check(b < pt->nups); + break; + } + case OP_GETGLOBAL: + case OP_SETGLOBAL: { + check(ttisstring(&pt->k[b])); + break; + } + case OP_SELF: { + checkreg(pt, a+1); + if (reg == a+1) last = pc; + break; + } + case OP_CONCAT: { + check(b < c); /* at least two operands */ + break; + } + case OP_TFORLOOP: { + check(c >= 1); /* at least one result (control variable) */ + checkreg(pt, a+2+c); /* space for results */ + if (reg >= a+2) last = pc; /* affect all regs above its base */ + break; + } + case OP_FORLOOP: + case OP_FORPREP: + checkreg(pt, a+3); + /* go through */ + case OP_JMP: { + int dest = pc+1+b; + /* not full check and jump is forward and do not skip `lastpc'? */ + if (reg != NO_REG && pc < dest && dest <= lastpc) + pc += b; /* do the jump */ + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (b != 0) { + checkreg(pt, a+b-1); + } + c--; /* c = num. returns */ + if (c == LUA_MULTRET) { + check(checkopenop(pt, pc)); + } + else if (c != 0) + checkreg(pt, a+c-1); + if (reg >= a) last = pc; /* affect all registers above base */ + break; + } + case OP_RETURN: { + b--; /* b = num. returns */ + if (b > 0) checkreg(pt, a+b-1); + break; + } + case OP_SETLIST: { + if (b > 0) checkreg(pt, a + b); + if (c == 0) pc++; + break; + } + case OP_CLOSURE: { + int nup, j; + check(b < pt->sizep); + nup = pt->p[b]->nups; + check(pc + nup < pt->sizecode); + for (j = 1; j <= nup; j++) { + OpCode op1 = GET_OPCODE(pt->code[pc + j]); + check(op1 == OP_GETUPVAL || op1 == OP_MOVE); + } + if (reg != NO_REG) /* tracing? */ + pc += nup; /* do not 'execute' these pseudo-instructions */ + break; + } + case OP_VARARG: { + check((pt->is_vararg & VARARG_ISVARARG) && + !(pt->is_vararg & VARARG_NEEDSARG)); + b--; + if (b == LUA_MULTRET) check(checkopenop(pt, pc)); + checkreg(pt, a+b-1); + break; + } + default: break; + } + } + return pt->code[last]; +} + +#undef check +#undef checkjump +#undef checkreg + +/* }====================================================== */ + + +int luaG_checkcode (const Proto *pt) { + return (symbexec(pt, pt->sizecode, NO_REG) != 0); +} + + +static const char *kname (Proto *p, int c) { + if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) + return svalue(&p->k[INDEXK(c)]); + else + return "?"; +} + + +static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, + const char **name) { + if (isLua(ci)) { /* a Lua function? */ + Proto *p = ci_func(ci)->l.p; + int pc = currentpc(L, ci); + Instruction i; + *name = luaF_getlocalname(p, stackpos+1, pc); + if (*name) /* is a local? */ + return "local"; + i = symbexec(p, pc, stackpos); /* try symbolic execution */ + lua_assert(pc != -1); + switch (GET_OPCODE(i)) { + case OP_GETGLOBAL: { + int g = GETARG_Bx(i); /* global index */ + lua_assert(ttisstring(&p->k[g])); + *name = svalue(&p->k[g]); + return "global"; + } + case OP_MOVE: { + int a = GETARG_A(i); + int b = GETARG_B(i); /* move from `b' to `a' */ + if (b < a) + return getobjname(L, ci, b, name); /* get name for `b' */ + break; + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "field"; + } + case OP_GETUPVAL: { + int u = GETARG_B(i); /* upvalue index */ + *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; + return "upvalue"; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "method"; + } + default: break; + } + } + return NULL; /* no useful name found */ +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + Instruction i; + if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) + return NULL; /* calling function is not Lua (or is unknown) */ + ci--; /* calling function */ + i = ci_func(ci)->l.p->code[currentpc(L, ci)]; + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || + GET_OPCODE(i) == OP_TFORLOOP) + return getobjname(L, ci, GETARG_A(i), name); + else + return NULL; /* no useful name can be found */ +} + + +/* only ANSI way to check whether a pointer points to an array */ +static int isinstack (CallInfo *ci, const TValue *o) { + StkId p; + for (p = ci->base; p < ci->top; p++) + if (o == p) return 1; + return 0; +} + + +void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + const char *name = NULL; + const char *t = luaT_typenames[ttype(o)]; + const char *kind = (isinstack(L->ci, o)) ? + getobjname(L, L->ci, cast_int(o - L->base), &name) : + NULL; + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + + +void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); +} + + +void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); +} + + +int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = luaT_typenames[ttype(p1)]; + const char *t2 = luaT_typenames[ttype(p2)]; + if (t1[2] == t2[2]) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); + return 0; +} + + +static void addinfo (lua_State *L, const char *msg) { + CallInfo *ci = L->ci; + if (isLua(ci)) { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(L, ci); + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } +} + + +void luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + incr_top(L); + luaD_call(L, L->top - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +void luaG_runerror (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); +} + === added file 'lua/ldebug.h' --- lua/ldebug.h 1970-01-01 00:00:00 +0000 +++ lua/ldebug.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,33 @@ +/* +** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + + +LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_checkcode (const Proto *pt); +LUAI_FUNC int luaG_checkopenop (Instruction i); + +#endif === added file 'lua/ldo.c' --- lua/ldo.c 1970-01-01 00:00:00 +0000 +++ lua/ldo.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,520 @@ +/* +** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define ldo_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { + setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + case LUA_ERRSYNTAX: + case LUA_ERRRUN: { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +static void restore_stack_limit (lua_State *L) { + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ + int inuse = cast_int(L->ci - L->base_ci); + if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ + luaD_reallocCI(L, LUAI_MAXCALLS); + } +} + + +static void resetstack (lua_State *L, int status) { + L->ci = L->base_ci; + L->base = L->ci->base; + luaF_close(L, L->base); /* close eventual pending closures */ + luaD_seterrorobj(L, status, L->base); + L->nCcalls = L->baseCcalls; + L->allowhook = 1; + restore_stack_limit(L); + L->errfunc = 0; + L->errorJmp = NULL; +} + + +void luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { + L->errorJmp->status = errcode; + LUAI_THROW(L, L->errorJmp); + } + else { + L->status = cast_byte(errcode); + if (G(L)->panic) { + resetstack(L, errcode); + lua_unlock(L); + G(L)->panic(L); + } + exit(EXIT_FAILURE); + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + struct lua_longjmp lj; + lj.status = 0; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + return lj.status; +} + +/* }====================================================== */ + + +static void correctstack (lua_State *L, TValue *oldstack) { + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->base_ci; ci <= L->ci; ci++) { + ci->top = (ci->top - oldstack) + L->stack; + ci->base = (ci->base - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + } + L->base = (L->base - oldstack) + L->stack; +} + + +void luaD_reallocstack (lua_State *L, int newsize) { + TValue *oldstack = L->stack; + int realsize = newsize + 1 + EXTRA_STACK; + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); + L->stacksize = realsize; + L->stack_last = L->stack+newsize; + correctstack(L, oldstack); +} + + +void luaD_reallocCI (lua_State *L, int newsize) { + CallInfo *oldci = L->base_ci; + luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); + L->size_ci = newsize; + L->ci = (L->ci - oldci) + L->base_ci; + L->end_ci = L->base_ci + L->size_ci - 1; +} + + +void luaD_growstack (lua_State *L, int n) { + if (n <= L->stacksize) /* double size is enough? */ + luaD_reallocstack(L, 2*L->stacksize); + else + luaD_reallocstack(L, L->stacksize + n); +} + + +static CallInfo *growCI (lua_State *L) { + if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ + luaD_throw(L, LUA_ERRERR); + else { + luaD_reallocCI(L, 2*L->size_ci); + if (L->size_ci > LUAI_MAXCALLS) + luaG_runerror(L, "stack overflow"); + } + return ++L->ci; +} + + +void luaD_callhook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, L->ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + if (event == LUA_HOOKTAILRET) + ar.i_ci = 0; /* tail call; no debug information about it */ + else + ar.i_ci = cast_int(L->ci - L->base_ci); + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + L->ci->top = L->top + LUA_MINSTACK; + lua_assert(L->ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + L->ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + } +} + + +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { + int i; + int nfixargs = p->numparams; + Table *htab = NULL; + StkId base, fixed; + for (; actual < nfixargs; ++actual) + setnilvalue(L->top++); +#if defined(LUA_COMPAT_VARARG) + if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ + int nvar = actual - nfixargs; /* number of extra arguments */ + lua_assert(p->is_vararg & VARARG_HASARG); + luaC_checkGC(L); + htab = luaH_new(L, nvar, 1); /* create `arg' table */ + for (i=0; itop - nvar + i); + /* store counter in field `n' */ + setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); + } +#endif + /* move fixed parameters to final position */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i=0; itop++, fixed+i); + setnilvalue(fixed+i); + } + /* add `arg' parameter */ + if (htab) { + sethvalue(L, L->top++, htab); + lua_assert(iswhite(obj2gco(htab))); + } + return base; +} + + +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; +} + + + +#define inc_ci(L) \ + ((L->ci == L->end_ci) ? growCI(L) : \ + (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) + + +int luaD_precall (lua_State *L, StkId func, int nresults) { + LClosure *cl; + ptrdiff_t funcr; + if (!ttisfunction(func)) /* `func' is not a function? */ + func = tryfuncTM(L, func); /* check the `function' tag method */ + funcr = savestack(L, func); + cl = &clvalue(func)->l; + L->ci->savedpc = L->savedpc; + if (!cl->isC) { /* Lua function? prepare its call */ + CallInfo *ci; + StkId st, base; + Proto *p = cl->p; + luaD_checkstack(L, p->maxstacksize); + func = restorestack(L, funcr); + if (!p->is_vararg) { /* no varargs? */ + base = func + 1; + if (L->top > base + p->numparams) + L->top = base + p->numparams; + } + else { /* vararg function */ + int nargs = cast_int(L->top - func) - 1; + base = adjust_varargs(L, p, nargs); + func = restorestack(L, funcr); /* previous call may change the stack */ + } + ci = inc_ci(L); /* now `enter' new function */ + ci->func = func; + L->base = ci->base = base; + ci->top = L->base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + L->savedpc = p->code; /* starting point */ + ci->tailcalls = 0; + ci->nresults = nresults; + for (st = L->top; st < ci->top; st++) + setnilvalue(st); + L->top = ci->top; + if (L->hookmask & LUA_MASKCALL) { + L->savedpc++; /* hooks assume 'pc' is already incremented */ + luaD_callhook(L, LUA_HOOKCALL, -1); + L->savedpc--; /* correct 'pc' */ + } + return PCRLUA; + } + else { /* if is a C function, call it */ + CallInfo *ci; + int n; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = inc_ci(L); /* now `enter' new function */ + ci->func = restorestack(L, funcr); + L->base = ci->base = ci->func + 1; + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->nresults = nresults; + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*curr_func(L)->c.f)(L); /* do the actual call */ + lua_lock(L); + if (n < 0) /* yielding? */ + return PCRYIELD; + else { + luaD_poscall(L, L->top - n); + return PCRC; + } + } +} + + +static StkId callrethooks (lua_State *L, StkId firstResult) { + ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ + luaD_callhook(L, LUA_HOOKRET, -1); + if (f_isLua(L->ci)) { /* Lua function? */ + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ + luaD_callhook(L, LUA_HOOKTAILRET, -1); + } + return restorestack(L, fr); +} + + +int luaD_poscall (lua_State *L, StkId firstResult) { + StkId res; + int wanted, i; + CallInfo *ci; + if (L->hookmask & LUA_MASKRET) + firstResult = callrethooks(L, firstResult); + ci = L->ci--; + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->base = (ci - 1)->base; /* restore base */ + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) + setobjs2s(L, res++, firstResult++); + while (i-- > 0) + setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + if (++L->nCcalls >= LUAI_MAXCCALLS) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ + luaV_execute(L, 1); /* call it */ + L->nCcalls--; + luaC_checkGC(L); +} + + +static void resume (lua_State *L, void *ud) { + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (L->status == 0) { /* start coroutine? */ + lua_assert(ci == L->base_ci && firstArg > L->base); + if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) + return; + } + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = 0; + if (!f_isLua(ci)) { /* `common' yield? */ + /* finish interrupted execution of `OP_CALL' */ + lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || + GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); + if (luaD_poscall(L, firstArg)) /* complete it... */ + L->top = L->ci->top; /* and correct top if not multiple results */ + } + else /* yielded inside a hook: just continue its execution */ + L->base = L->ci->base; + } + luaV_execute(L, cast_int(L->ci - L->base_ci)); +} + + +static int resume_error (lua_State *L, const char *msg) { + L->top = L->ci->base; + setsvalue2s(L, L->top, luaS_new(L, msg)); + incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + +LUA_API int lua_resume (lua_State *L, int nargs) { + int status; + lua_lock(L); + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) + return resume_error(L, "cannot resume non-suspended coroutine"); + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow"); + luai_userstateresume(L, nargs); + lua_assert(L->errfunc == 0); + L->baseCcalls = ++L->nCcalls; + status = luaD_rawrunprotected(L, resume, L->top - nargs); + if (status != 0) { /* error? */ + L->status = cast_byte(status); /* mark thread as `dead' */ + luaD_seterrorobj(L, status, L->top); + L->ci->top = L->top; + } + else { + lua_assert(L->nCcalls == L->baseCcalls); + status = L->status; + } + --L->nCcalls; + lua_unlock(L); + return status; +} + + +LUA_API int lua_yield (lua_State *L, int nresults) { + luai_userstateyield(L, nresults); + lua_lock(L); + if (L->nCcalls > L->baseCcalls) + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + L->base = L->top - nresults; /* protect stack slots below */ + L->status = LUA_YIELD; + lua_unlock(L); + return -1; +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + unsigned short oldnCcalls = L->nCcalls; + ptrdiff_t old_ci = saveci(L, L->ci); + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != 0) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close eventual pending closures */ + luaD_seterrorobj(L, status, oldtop); + L->nCcalls = oldnCcalls; + L->ci = restoreci(L, old_ci); + L->base = L->ci->base; + L->savedpc = L->ci->savedpc; + L->allowhook = old_allowhooks; + restore_stack_limit(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* buffer to be used by the scanner */ + const char *name; +}; + +static void f_parser (lua_State *L, void *ud) { + int i; + Proto *tf; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = luaZ_lookahead(p->z); + luaC_checkGC(L); + tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, + &p->buff, p->name); + cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); + cl->l.p = tf; + for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ + cl->l.upvals[i] = luaF_newupval(L); + setclvalue(L, L->top, cl); + incr_top(L); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { + struct SParser p; + int status; + p.z = z; p.name = name; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + return status; +} + + === added file 'lua/ldo.h' --- lua/ldo.h 1970-01-01 00:00:00 +0000 +++ lua/ldo.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,57 @@ +/* +** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +#define luaD_checkstack(L,n) \ + if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ + luaD_growstack(L, n); \ + else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); + + +#define incr_top(L) {luaD_checkstack(L,1); L->top++;} + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) + +#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) +#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) + + +/* results from luaD_precall */ +#define PCRLUA 0 /* initiated a call to a Lua function */ +#define PCRC 1 /* did a call to a C function */ +#define PCRYIELD 2 /* C funtion yielded */ + + +/* type of protected functions, to be ran by `runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); +LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); +LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack (lua_State *L, int n); + +LUAI_FUNC void luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); + +#endif + === added file 'lua/ldump.c' --- lua/ldump.c 1970-01-01 00:00:00 +0000 +++ lua/ldump.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,166 @@ +/* +** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define ldump_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +typedef struct { + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; +} DumpState; + +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) + +static void DumpBlock(const void* b, size_t size, DumpState* D) +{ + if (D->status==0) + { + lua_unlock(D->L); + D->status=(*D->writer)(D->L,b,size,D->data); + lua_lock(D->L); + } +} + +static void DumpChar(int y, DumpState* D) +{ + char x=(char)y; + DumpVar(x,D); +} + +static void DumpInt(int x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpNumber(lua_Number x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpVector(const void* b, int n, size_t size, DumpState* D) +{ + DumpInt(n,D); + DumpMem(b,n,size,D); +} + +static void DumpString(const TString* s, DumpState* D) +{ + if (s==NULL || getstr(s)==NULL) + { + size_t size=0; + DumpVar(size,D); + } + else + { + size_t size=s->tsv.len+1; /* include trailing '\0' */ + DumpVar(size,D); + DumpBlock(getstr(s),size,D); + } +} + +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D); + +static void DumpConstants(const Proto* f, DumpState* D) +{ + int i,n=f->sizek; + DumpInt(n,D); + for (i=0; ik[i]; + DumpChar(ttype(o),D); + switch (ttype(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o),D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o),D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o),D); + break; + default: + lua_assert(0); /* cannot happen */ + break; + } + } + n=f->sizep; + DumpInt(n,D); + for (i=0; ip[i],f->source,D); +} + +static void DumpDebug(const Proto* f, DumpState* D) +{ + int i,n; + n= (D->strip) ? 0 : f->sizelineinfo; + DumpVector(f->lineinfo,n,sizeof(int),D); + n= (D->strip) ? 0 : f->sizelocvars; + DumpInt(n,D); + for (i=0; ilocvars[i].varname,D); + DumpInt(f->locvars[i].startpc,D); + DumpInt(f->locvars[i].endpc,D); + } + n= (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i],D); +} + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D) +{ + DumpString((f->source==p || D->strip) ? NULL : f->source,D); + DumpInt(f->linedefined,D); + DumpInt(f->lastlinedefined,D); + DumpChar(f->nups,D); + DumpChar(f->numparams,D); + DumpChar(f->is_vararg,D); + DumpChar(f->maxstacksize,D); + DumpCode(f,D); + DumpConstants(f,D); + DumpDebug(f,D); +} + +static void DumpHeader(DumpState* D) +{ + char h[LUAC_HEADERSIZE]; + luaU_header(h); + DumpBlock(h,LUAC_HEADERSIZE,D); +} + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +{ + DumpState D; + D.L=L; + D.writer=w; + D.data=data; + D.strip=strip; + D.status=0; + DumpHeader(&D); + DumpFunction(f,NULL,&D); + return D.status; +} === added file 'lua/lfunc.c' --- lua/lfunc.c 1970-01-01 00:00:00 +0000 +++ lua/lfunc.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,176 @@ +/* +** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lfunc_c +#define LUA_CORE + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->c.isC = 1; + c->c.env = e; + c->c.nupvalues = cast_byte(nelems); + return c; +} + + +Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->l.isC = 0; + c->l.env = e; + c->l.nupvalues = cast_byte(nelems); + while (nelems--) c->l.upvals[nelems] = NULL; + return c; +} + + +UpVal *luaF_newupval (lua_State *L) { + UpVal *uv = luaM_new(L, UpVal); + luaC_link(L, obj2gco(uv), LUA_TUPVAL); + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { + lua_assert(p->v != &p->u.value); + if (p->v == level) { /* found a corresponding upvalue? */ + if (isdead(g, obj2gco(p))) /* is it dead? */ + changewhite(obj2gco(p)); /* ressurect it */ + return p; + } + pp = &p->next; + } + uv = luaM_new(L, UpVal); /* not found: create a new one */ + uv->tt = LUA_TUPVAL; + uv->marked = luaC_white(g); + uv->v = level; /* current value lives in the stack */ + uv->next = *pp; /* chain it in the proper position */ + *pp = obj2gco(uv); + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; +} + + +static void unlinkupval (UpVal *uv) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; +} + + +void luaF_freeupval (lua_State *L, UpVal *uv) { + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else { + unlinkupval(uv); + setobj(L, &uv->u.value, uv->v); + uv->v = &uv->u.value; /* now current value lives here */ + luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ + } + } +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = luaM_new(L, Proto); + luaC_link(L, obj2gco(f), LUA_TPROTO); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->sizelineinfo = 0; + f->sizeupvalues = 0; + f->nups = 0; + f->upvalues = NULL; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->lineinfo = NULL; + f->sizelocvars = 0; + f->locvars = NULL; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode, Instruction); + luaM_freearray(L, f->p, f->sizep, Proto *); + luaM_freearray(L, f->k, f->sizek, TValue); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + luaM_free(L, f); +} + + +void luaF_freeclosure (lua_State *L, Closure *c) { + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : + sizeLclosure(c->l.nupvalues); + luaM_freemem(L, c, size); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + === added file 'lua/lfunc.h' --- lua/lfunc.h 1970-01-01 00:00:00 +0000 +++ lua/lfunc.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,34 @@ +/* +** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *)*((n)-1))) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif === added file 'lua/lgc.c' --- lua/lgc.c 1970-01-01 00:00:00 +0000 +++ lua/lgc.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,713 @@ +/* +** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lgc_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define GCSTEPSIZE 1024u +#define GCSWEEPMAX 40 +#define GCSWEEPCOST 10 +#define GCFINALIZECOST 100 + + +#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) + +#define makewhite(g,x) \ + ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) + +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) + +#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) + + +#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) +#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) + + +#define KEYWEAK bitmask(KEYWEAKBIT) +#define VALUEWEAK bitmask(VALUEWEAKBIT) + + + +#define markvalue(g,o) { checkconsistency(o); \ + if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } + +#define markobject(g,t) { if (iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); } + + +#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) + + +static void removeentry (Node *n) { + lua_assert(ttisnil(gval(n))); + if (iscollectable(gkey(n))) + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ +} + + +static void reallymarkobject (global_State *g, GCObject *o) { + lua_assert(iswhite(o) && !isdead(g, o)); + white2gray(o); + switch (o->gch.tt) { + case LUA_TSTRING: { + return; + } + case LUA_TUSERDATA: { + Table *mt = gco2u(o)->metatable; + gray2black(o); /* udata are never gray */ + if (mt) markobject(g, mt); + markobject(g, gco2u(o)->env); + return; + } + case LUA_TUPVAL: { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v == &uv->u.value) /* closed? */ + gray2black(o); /* open upvalues are never black */ + return; + } + case LUA_TFUNCTION: { + gco2cl(o)->c.gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTABLE: { + gco2h(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTHREAD: { + gco2th(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TPROTO: { + gco2p(o)->gclist = g->gray; + g->gray = o; + break; + } + default: lua_assert(0); + } +} + + +static void marktmu (global_State *g) { + GCObject *u = g->tmudata; + if (u) { + do { + u = u->gch.next; + makewhite(g, u); /* may be marked, if left from previous GC */ + reallymarkobject(g, u); + } while (u != g->tmudata); + } +} + + +/* move `dead' udata that need finalization to list `tmudata' */ +size_t luaC_separateudata (lua_State *L, int all) { + global_State *g = G(L); + size_t deadmem = 0; + GCObject **p = &g->mainthread->next; + GCObject *curr; + while ((curr = *p) != NULL) { + if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) + p = &curr->gch.next; /* don't bother with them */ + else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { + markfinalized(gco2u(curr)); /* don't need finalization */ + p = &curr->gch.next; + } + else { /* must call its gc method */ + deadmem += sizeudata(gco2u(curr)); + markfinalized(gco2u(curr)); + *p = curr->gch.next; + /* link `curr' at the end of `tmudata' list */ + if (g->tmudata == NULL) /* list is empty? */ + g->tmudata = curr->gch.next = curr; /* creates a circular list */ + else { + curr->gch.next = g->tmudata->gch.next; + g->tmudata->gch.next = curr; + g->tmudata = curr; + } + } + } + return deadmem; +} + + +static int traversetable (global_State *g, Table *h) { + int i; + int weakkey = 0; + int weakvalue = 0; + const TValue *mode; + if (h->metatable) + markobject(g, h->metatable); + mode = gfasttm(g, h->metatable, TM_MODE); + if (mode && ttisstring(mode)) { /* is there a weak mode? */ + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + if (weakkey || weakvalue) { /* is really weak? */ + h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ + h->marked |= cast_byte((weakkey << KEYWEAKBIT) | + (weakvalue << VALUEWEAKBIT)); + h->gclist = g->weak; /* must be cleared after GC, ... */ + g->weak = obj2gco(h); /* ... so put in the appropriate list */ + } + } + if (weakkey && weakvalue) return 1; + if (!weakvalue) { + i = h->sizearray; + while (i--) + markvalue(g, &h->array[i]); + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + if (ttisnil(gval(n))) + removeentry(n); /* remove empty entries */ + else { + lua_assert(!ttisnil(gkey(n))); + if (!weakkey) markvalue(g, gkey(n)); + if (!weakvalue) markvalue(g, gval(n)); + } + } + return weakkey || weakvalue; +} + + +/* +** All marks are conditional because a GC may happen while the +** prototype is still being created +*/ +static void traverseproto (global_State *g, Proto *f) { + int i; + if (f->source) stringmark(f->source); + for (i=0; isizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i=0; isizeupvalues; i++) { /* mark upvalue names */ + if (f->upvalues[i]) + stringmark(f->upvalues[i]); + } + for (i=0; isizep; i++) { /* mark nested protos */ + if (f->p[i]) + markobject(g, f->p[i]); + } + for (i=0; isizelocvars; i++) { /* mark local-variable names */ + if (f->locvars[i].varname) + stringmark(f->locvars[i].varname); + } +} + + + +static void traverseclosure (global_State *g, Closure *cl) { + markobject(g, cl->c.env); + if (cl->c.isC) { + int i; + for (i=0; ic.nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->c.upvalue[i]); + } + else { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nups); + markobject(g, cl->l.p); + for (i=0; il.nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->l.upvals[i]); + } +} + + +static void checkstacksizes (lua_State *L, StkId max) { + int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ + int s_used = cast_int(max - L->stack); /* part of stack in use */ + if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ + return; /* do not touch the stacks */ + if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) + luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ + condhardstacktests(luaD_reallocCI(L, ci_used + 1)); + if (4*s_used < L->stacksize && + 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) + luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ + condhardstacktests(luaD_reallocstack(L, s_used)); +} + + +static void traversestack (global_State *g, lua_State *l) { + StkId o, lim; + CallInfo *ci; + markvalue(g, gt(l)); + lim = l->top; + for (ci = l->base_ci; ci <= l->ci; ci++) { + lua_assert(ci->top <= l->stack_last); + if (lim < ci->top) lim = ci->top; + } + for (o = l->stack; o < l->top; o++) + markvalue(g, o); + for (; o <= lim; o++) + setnilvalue(o); + checkstacksizes(l, lim); +} + + +/* +** traverse one gray object, turning it to black. +** Returns `quantity' traversed. +*/ +static l_mem propagatemark (global_State *g) { + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (o->gch.tt) { + case LUA_TTABLE: { + Table *h = gco2h(o); + g->gray = h->gclist; + if (traversetable(g, h)) /* table is weak? */ + black2gray(o); /* keep it gray */ + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * sizenode(h); + } + case LUA_TFUNCTION: { + Closure *cl = gco2cl(o); + g->gray = cl->c.gclist; + traverseclosure(g, cl); + return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : + sizeLclosure(cl->l.nupvalues); + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; + th->gclist = g->grayagain; + g->grayagain = o; + black2gray(o); + traversestack(g, th); + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * th->size_ci; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; + traverseproto(g, p); + return sizeof(Proto) + sizeof(Instruction) * p->sizecode + + sizeof(Proto *) * p->sizep + + sizeof(TValue) * p->sizek + + sizeof(int) * p->sizelineinfo + + sizeof(LocVar) * p->sizelocvars + + sizeof(TString *) * p->sizeupvalues; + } + default: lua_assert(0); return 0; + } +} + + +static size_t propagateall (global_State *g) { + size_t m = 0; + while (g->gray) m += propagatemark(g); + return m; +} + + +/* +** The next function tells whether a key or value can be cleared from +** a weak table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them; for userdata +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (const TValue *o, int iskey) { + if (!iscollectable(o)) return 0; + if (ttisstring(o)) { + stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + return iswhite(gcvalue(o)) || + (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); +} + + +/* +** clear collected entries from weaktables +*/ +static void cleartable (GCObject *l) { + while (l) { + Table *h = gco2h(l); + int i = h->sizearray; + lua_assert(testbit(h->marked, VALUEWEAKBIT) || + testbit(h->marked, KEYWEAKBIT)); + if (testbit(h->marked, VALUEWEAKBIT)) { + while (i--) { + TValue *o = &h->array[i]; + if (iscleared(o, 0)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + if (!ttisnil(gval(n)) && /* non-empty entry? */ + (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* remove entry from table */ + } + } + l = h->gclist; + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->gch.tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TTABLE: luaH_free(L, gco2h(o)); break; + case LUA_TTHREAD: { + lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); + luaE_freethread(L, gco2th(o)); + break; + } + case LUA_TSTRING: { + G(L)->strt.nuse--; + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + case LUA_TUSERDATA: { + luaM_freemem(L, o, sizeudata(gco2u(o))); + break; + } + default: lua_assert(0); + } +} + + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) + + +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + GCObject *curr; + global_State *g = G(L); + int deadmask = otherwhite(g); + while ((curr = *p) != NULL && count-- > 0) { + if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ + sweepwholelist(L, &gco2th(curr)->openupval); + if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ + lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); + makewhite(g, curr); /* make it white (for next cycle) */ + p = &curr->gch.next; + } + else { /* must erase `curr' */ + lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); + *p = curr->gch.next; + if (curr == g->rootgc) /* is the first element of the list? */ + g->rootgc = curr->gch.next; /* adjust first */ + freeobj(L, curr); + } + } + return p; +} + + +static void checkSizes (lua_State *L) { + global_State *g = G(L); + /* check size of string hash */ + if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && + g->strt.size > MINSTRTABSIZE*2) + luaS_resize(L, g->strt.size/2); /* table is too big */ + /* check size of buffer */ + if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ + size_t newsize = luaZ_sizebuffer(&g->buff) / 2; + luaZ_resizebuffer(L, &g->buff, newsize); + } +} + + +static void GCTM (lua_State *L) { + global_State *g = G(L); + GCObject *o = g->tmudata->gch.next; /* get first element */ + Udata *udata = rawgco2u(o); + const TValue *tm; + /* remove udata from `tmudata' */ + if (o == g->tmudata) /* last element? */ + g->tmudata = NULL; + else + g->tmudata->gch.next = udata->uv.next; + udata->uv.next = g->mainthread->next; /* return it to `root' list */ + g->mainthread->next = o; + makewhite(g, o); + tm = fasttm(L, udata->uv.metatable, TM_GC); + if (tm != NULL) { + lu_byte oldah = L->allowhook; + lu_mem oldt = g->GCthreshold; + L->allowhook = 0; /* stop debug hooks during GC tag method */ + g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ + setobj2s(L, L->top, tm); + setuvalue(L, L->top+1, udata); + L->top += 2; + luaD_call(L, L->top - 2, 0); + L->allowhook = oldah; /* restore hooks */ + g->GCthreshold = oldt; /* restore threshold */ + } +} + + +/* +** Call all GC tag methods +*/ +void luaC_callGCTM (lua_State *L) { + while (G(L)->tmudata) + GCTM(L); +} + + +void luaC_freeall (lua_State *L) { + global_State *g = G(L); + int i; + g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ + sweepwholelist(L, &g->rootgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); +} + + +static void markmt (global_State *g) { + int i; + for (i=0; imt[i]) markobject(g, g->mt[i]); +} + + +/* mark root set */ +static void markroot (lua_State *L) { + global_State *g = G(L); + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + markobject(g, g->mainthread); + /* make global table be traversed before main stack */ + markvalue(g, gt(g->mainthread)); + markvalue(g, registry(L)); + markmt(g); + g->gcstate = GCSpropagate; +} + + +static void remarkupvals (global_State *g) { + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } +} + + +static void atomic (lua_State *L) { + global_State *g = G(L); + size_t udsize; /* total size of userdata to be finalized */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + /* traverse objects cautch by write barrier and by 'remarkupvals' */ + propagateall(g); + /* remark weak tables */ + g->gray = g->weak; + g->weak = NULL; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + markmt(g); /* mark basic metatables (again) */ + propagateall(g); + /* remark gray again */ + g->gray = g->grayagain; + g->grayagain = NULL; + propagateall(g); + udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ + marktmu(g); /* mark `preserved' userdata */ + udsize += propagateall(g); /* remark, to propagate `preserveness' */ + cleartable(g->weak); /* remove collected objects from weak tables */ + /* flip current white */ + g->currentwhite = cast_byte(otherwhite(g)); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gcstate = GCSsweepstring; + g->estimate = g->totalbytes - udsize; /* first estimate */ +} + + +static l_mem singlestep (lua_State *L) { + global_State *g = G(L); + /*lua_checkmemory(L);*/ + switch (g->gcstate) { + case GCSpause: { + markroot(L); /* start a new collection */ + return 0; + } + case GCSpropagate: { + if (g->gray) + return propagatemark(g); + else { /* no more `gray' objects */ + atomic(L); /* finish mark phase */ + return 0; + } + } + case GCSsweepstring: { + lu_mem old = g->totalbytes; + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); + if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ + g->gcstate = GCSsweep; /* end sweep-string phase */ + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPCOST; + } + case GCSsweep: { + lu_mem old = g->totalbytes; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + if (*g->sweepgc == NULL) { /* nothing more to sweep? */ + checkSizes(L); + g->gcstate = GCSfinalize; /* end sweep phase */ + } + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPMAX*GCSWEEPCOST; + } + case GCSfinalize: { + if (g->tmudata) { + GCTM(L); + if (g->estimate > GCFINALIZECOST) + g->estimate -= GCFINALIZECOST; + return GCFINALIZECOST; + } + else { + g->gcstate = GCSpause; /* end collection */ + g->gcdept = 0; + return 0; + } + } + default: lua_assert(0); return 0; + } +} + + +void luaC_step (lua_State *L) { + global_State *g = G(L); + l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; + if (lim == 0) + lim = (MAX_LUMEM-1)/2; /* no limit */ + g->gcdept += g->totalbytes - g->GCthreshold; + do { + lim -= singlestep(L); + if (g->gcstate == GCSpause) + break; + } while (lim > 0); + if (g->gcstate != GCSpause) { + if (g->gcdept < GCSTEPSIZE) + g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ + else { + g->gcdept -= GCSTEPSIZE; + g->GCthreshold = g->totalbytes; + } + } + else { + lua_assert(g->totalbytes >= g->estimate); + setthreshold(g); + } +} + + +void luaC_fullgc (lua_State *L) { + global_State *g = G(L); + if (g->gcstate <= GCSpropagate) { + /* reset sweep marks to sweep all elements (returning them to white) */ + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + /* reset other collector lists */ + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->gcstate = GCSsweepstring; + } + lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); + /* finish any pending sweep phase */ + while (g->gcstate != GCSfinalize) { + lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); + singlestep(L); + } + markroot(L); + while (g->gcstate != GCSpause) { + singlestep(L); + } + setthreshold(g); +} + + +void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + lua_assert(ttype(&o->gch) != LUA_TTABLE); + /* must keep invariant? */ + if (g->gcstate == GCSpropagate) + reallymarkobject(g, v); /* restore invariant */ + else /* don't mind */ + makewhite(g, o); /* mark as white just to avoid other barriers */ +} + + +void luaC_barrierback (lua_State *L, Table *t) { + global_State *g = G(L); + GCObject *o = obj2gco(t); + lua_assert(isblack(o) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + black2gray(o); /* make table gray (again) */ + t->gclist = g->grayagain; + g->grayagain = o; +} + + +void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { + global_State *g = G(L); + o->gch.next = g->rootgc; + g->rootgc = o; + o->gch.marked = luaC_white(g); + o->gch.tt = tt; +} + + +void luaC_linkupval (lua_State *L, UpVal *uv) { + global_State *g = G(L); + GCObject *o = obj2gco(uv); + o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ + g->rootgc = o; + if (isgray(o)) { + if (g->gcstate == GCSpropagate) { + gray2black(o); /* closed upvalues need barrier */ + luaC_barrier(L, uv, uv->v); + } + else { /* sweep phase: sweep it (turning it into white) */ + makewhite(g, o); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + } + } +} + === added file 'lua/lgc.h' --- lua/lgc.h 1970-01-01 00:00:00 +0000 +++ lua/lgc.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,110 @@ +/* +** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpause 0 +#define GCSpropagate 1 +#define GCSsweepstring 2 +#define GCSsweep 3 +#define GCSfinalize 4 + + +/* +** some userful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) +#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) +#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) +#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) + + + +/* +** Layout for bit use in `marked' field: +** bit 0 - object is white (type 0) +** bit 1 - object is white (type 1) +** bit 2 - object is black +** bit 3 - for userdata: has been finalized +** bit 3 - for tables: has weak keys +** bit 4 - for tables: has weak values +** bit 5 - object is fixed (should not be collected) +** bit 6 - object is "super" fixed (only the main thread) +*/ + + +#define WHITE0BIT 0 +#define WHITE1BIT 1 +#define BLACKBIT 2 +#define FINALIZEDBIT 3 +#define KEYWEAKBIT 3 +#define VALUEWEAKBIT 4 +#define FIXEDBIT 5 +#define SFIXEDBIT 6 +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) (!isblack(x) && !iswhite(x)) + +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) + +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) + + +#define luaC_checkGC(L) { \ + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ + if (G(L)->totalbytes >= G(L)->GCthreshold) \ + luaC_step(L); } + + +#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),gcvalue(v)); } + +#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ + luaC_barrierback(L,t); } + +#define luaC_objbarrier(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),obj2gco(o)); } + +#define luaC_objbarriert(L,t,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } + +LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); +LUAI_FUNC void luaC_callGCTM (lua_State *L); +LUAI_FUNC void luaC_freeall (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_fullgc (lua_State *L); +LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); +LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); +LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); + + +#endif === added file 'lua/linit.c' --- lua/linit.c 1970-01-01 00:00:00 +0000 +++ lua/linit.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,46 @@ +/* +** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ +** Initialization of libraries for lua.c +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +static const luaL_Reg lualibs[] = { + {"", luaopen_base}, +#ifndef USE_GRUB_LIB + {LUA_LOADLIBNAME, luaopen_package}, +#endif /* ! USE_GRUB_LIB */ + {LUA_TABLIBNAME, luaopen_table}, +#ifndef USE_GRUB_LIB + {LUA_IOLIBNAME, luaopen_io}, +#endif /* ! USE_GRUB_LIB */ +#ifndef USE_GRUB_LIB + {LUA_OSLIBNAME, luaopen_os}, +#endif /* ! USE_GRUB_LIB */ + {LUA_STRLIBNAME, luaopen_string}, +#if !defined LUA_NUMBER_INTEGRAL + {LUA_MATHLIBNAME, luaopen_math}, +#endif + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib = lualibs; + for (; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } +} + === added file 'lua/liolib.c' --- lua/liolib.c 1970-01-01 00:00:00 +0000 +++ lua/liolib.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,578 @@ +/* +** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define liolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +#define IO_INPUT 1 +#define IO_OUTPUT 2 + + +static const char *const fnames[] = {"input", "output"}; + + +static int pushresult (lua_State *L, int i, const char *filename) { + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, grub_errmsg); + else + lua_pushfstring(L, "%s", grub_errmsg); + lua_pushinteger(L, grub_errno); + return 3; + } +} + + +static void fileerror (lua_State *L, int arg, const char *filename) { + lua_pushfstring(L, "%s: %s", filename, grub_errmsg); + luaL_argerror(L, arg, lua_tostring(L, -1)); +} + + +#define tofilep(L) ((grub_file_t *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + + +static int io_type (lua_State *L) { + void *ud; + luaL_checkany(L, 1); + ud = lua_touserdata(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); + if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + lua_pushnil(L); /* not a file */ + else if (*((grub_file_t *)ud) == NULL) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static grub_file_t tofile (lua_State *L) { + grub_file_t *f = tofilep(L); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; +} + + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static grub_file_t *newfile (lua_State *L) { + grub_file_t *pf = (grub_file_t *)lua_newuserdata(L, sizeof(grub_file_t)); + *pf = NULL; /* file handle is currently `closed' */ + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return pf; +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + grub_file_t *p = tofilep(L); + int ok = (grub_file_close(*p) == 0); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +static int aux_close (lua_State *L) { + lua_getfenv(L, 1); + lua_getfield(L, -1, "__close"); + return (lua_tocfunction(L, -1))(L); +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); + tofile(L); /* make sure argument is a file */ + return aux_close(L); +} + + +static int io_gc (lua_State *L) { + grub_file_t f = *tofilep(L); + /* ignore closed files */ + if (f != NULL) + aux_close(L); + return 0; +} + + +static int io_tostring (lua_State *L) { + grub_file_t f = *tofilep(L); + if (f == NULL) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", f); + return 1; +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + grub_file_t *pf = newfile(L); + UNUSED(mode); + *pf = grub_buffile_open(filename, 0); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +static grub_file_t getiofile (lua_State *L, int findex) { + grub_file_t f; + lua_rawgeti(L, LUA_ENVIRONINDEX, findex); + f = *(grub_file_t *)lua_touserdata(L, -1); + if (f == NULL) + luaL_error(L, "standard %s file is closed", fnames[findex - 1]); + return f; +} + + +static int g_iofile (lua_State *L, int f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) { + grub_file_t *pf = newfile(L); + *pf = grub_buffile_open(filename, 0); + if (*pf == NULL) + fileerror(L, 1, filename); + } + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_rawseti(L, LUA_ENVIRONINDEX, f); + } + /* return current value */ + lua_rawgeti(L, LUA_ENVIRONINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +static void aux_lines (lua_State *L, int idx, int toclose) { + lua_pushvalue(L, idx); + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 2); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + if (lua_isnoneornil(L, 1)) { /* no arguments? */ + /* will iterate over default input */ + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); + return f_lines(L); + } + else { + const char *filename = luaL_checkstring(L, 1); + grub_file_t *pf = newfile(L); + *pf = grub_buffile_open(filename, 0); + if (*pf == NULL) + fileerror(L, 1, filename); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number (lua_State *L, grub_file_t f) { + lua_Number d; + char buf[32]; + char *endptr; + int len; + int found_digit; + len = 0; + found_digit = 0; + while (len < sizeof(buf) - 1) + { + if (grub_file_read (f, &buf[len], 1) != 1) + break; + + if (found_digit) + { + if (! isdigit (buf[len])) + break; + } + else + { + if (isdigit (buf[len])) + found_digit = 1; + } + + len++; + } + buf[len] = '\0'; + d = strtol (buf, &endptr, 10); + if (buf[0] != '\0' && endptr > &buf[0]) { + lua_pushnumber(L, d); + return 1; + } + else return 0; /* read fails */ +} + + +static int test_eof (lua_State *L, grub_file_t f) { + lua_pushlstring(L, NULL, 0); + return (grub_file_tell (f) < grub_file_size (f)); +} + + +static int read_line (lua_State *L, grub_file_t f) { + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l-1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} + + +static int read_chars (lua_State *L, grub_file_t f, size_t n) { + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do { + ssize_t ret; + char *p = luaL_prepbuffer(&b); + if (rlen > n) rlen = n; /* cannot read more than asked */ + ret = grub_file_read (f, p, rlen); + if (ret == -1) + break; + nr = (size_t) ret; + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_objlen(L, -1) > 0); +} + + +static int g_read (lua_State *L, grub_file_t f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + grub_errno = GRUB_ERR_NONE; + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (grub_errno != GRUB_ERR_NONE) + return pushresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +static int io_readline (lua_State *L) { + grub_file_t f = *(grub_file_t *)lua_touserdata(L, lua_upvalueindex(1)); + int sucess; + if (f == NULL) /* file is already closed? */ + luaL_error(L, "file is already closed"); + grub_errno = GRUB_ERR_NONE; + sucess = read_line(L, f); + if (grub_errno != GRUB_ERR_NONE) + return luaL_error(L, "%s", grub_errmsg); + if (sucess) return 1; + else { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, grub_file_t f, int arg) { + int nargs = lua_gettop(L) - 1; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + if (status) + { + char buf[32]; + size_t n; + grub_sprintf (buf, LUA_NUMBER_FMT, lua_tonumber (L, arg)); + n = strlen (buf); + status = (grub_file_write (f, buf, n) == n); + } + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (grub_file_write(f, s, l) == l); + } + } + return pushresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + return g_write(L, tofile(L), 2); +} + +enum { + SEEK_SET, SEEK_CUR, SEEK_END +}; + +static int do_grub_seek (grub_file_t f, long offset, int whence) +{ + grub_off_t pos; + switch (whence) + { + default: + case SEEK_SET: + pos = offset; + break; + case SEEK_CUR: + pos = ((long) grub_file_tell (f)) + offset; + break; + case SEEK_END: + pos = ((long) grub_file_size (f)) + offset; + break; + } + return grub_file_seek (f, pos); +} + +static int f_seek (lua_State *L) { + static const char *const modenames[] = {"set", "cur", "end", NULL}; + grub_file_t f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + long offset = luaL_optlong(L, 3, 0); + op = do_grub_seek (f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, grub_file_tell (f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + /* For GRUB we simply report success. */ + lua_pushboolean (L, 1); + return 1; +} + + + +static int io_flush (lua_State *L) { + /* For GRUB we simply report success. */ + lua_pushboolean (L, 1); + return 1; +} + + +static int f_flush (lua_State *L) { + /* For GRUB we simply report success. */ + lua_pushboolean (L, 1); + return 1; +} + + +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"read", io_read}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", io_gc}, + {"__tostring", io_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, flib); /* file methods */ +} + + +static void createstdfile (lua_State *L, grub_file_t f, int k, const char *fname) { + *newfile(L) = f; + if (k > 0) { + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_ENVIRONINDEX, k); + } + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); +} + + +LUALIB_API int luaopen_io (lua_State *L) { + createmeta(L); + /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ + newfenv(L, io_fclose); + lua_replace(L, LUA_ENVIRONINDEX); + /* open library */ + luaL_register(L, LUA_IOLIBNAME, iolib); + /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, 0, "stderr"); + lua_pop(L, 1); /* pop environment for default files */ + lua_getfield(L, -1, "popen"); + newfenv(L, io_pclose); /* create environment for 'popen' */ + lua_setfenv(L, -2); /* set fenv for 'popen' */ + lua_pop(L, 1); /* pop 'popen' */ + return 1; +} + === added file 'lua/llex.c' --- lua/llex.c 1970-01-01 00:00:00 +0000 +++ lua/llex.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,469 @@ +/* +** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define llex_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", + "", "", "", "", + NULL +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (b->n + 1 > b->buffsize) { + size_t newsize; + if (b->buffsize >= MAX_SIZET/2) + luaX_lexerror(ls, "lexical element too long", 0); + newsize = b->buffsize * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[b->n++] = cast(char, c); +} + + +void luaX_init (lua_State *L) { + int i; + for (i=0; itsv.reserved = cast_byte(i+1); /* reserved word */ + } +} + + +#define MAXSRC 80 + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { + lua_assert(token == cast(unsigned char, token)); + return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : + luaO_pushfstring(ls->L, "%c", token); + } + else + return luaX_tokens[token-FIRST_RESERVED]; +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaZ_buffer(ls->buff); + default: + return luaX_token2str(ls, token); + } +} + + +void luaX_lexerror (LexState *ls, const char *msg, int token) { + char buff[MAXSRC]; + luaO_chunkid(buff, getstr(ls->source), MAXSRC); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +void luaX_syntaxerror (LexState *ls, const char *msg) { + luaX_lexerror(ls, msg, ls->t.token); +} + + +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TString *ts = luaS_newlstr(L, str, l); + TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ + if (ttisnil(o)) + setbvalue(o, 1); /* make sure `str' will not be collected */ + return ts; +} + + +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + luaX_syntaxerror(ls, "chunk has too many lines"); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { + ls->decpoint = '.'; + ls->L = L; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ + next(ls); /* read first char */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + + +static int check_next (LexState *ls, const char *set) { + if (!strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; +} + + +static void buffreplace (LexState *ls, char from, char to) { + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) p[n] = to; +} + + +static void trydecpoint (LexState *ls, SemInfo *seminfo) { + /* format error: try to update decimal point separator */ + char old = ls->decpoint; + +#ifdef USE_GRUB_LIB + ls->decpoint = '.'; +#else /* ! USE_GRUB_LIB */ + struct lconv *cv = localeconv(); + ls->decpoint = (cv ? cv->decimal_point[0] : '.'); +#endif /* ! USE_GRUB_LIB */ + + buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + luaX_lexerror(ls, "malformed number", TK_NUMBER); + } +} + + +/* LUA_NUMBER */ +static void read_numeral (LexState *ls, SemInfo *seminfo) { + lua_assert(isdigit(ls->current)); + do { + save_and_next(ls); + } while (isdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Ee")) /* `E'? */ + check_next(ls, "+-"); /* optional exponent sign */ + while (isalnum(ls->current) || ls->current == '_') + save_and_next(ls); + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ +} + + +static int skip_sep (LexState *ls) { + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { + int cont = 0; + (void)(cont); /* avoid warnings when `cont' is not used */ + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ +#if defined(LUA_COMPAT_LSTR) + case '[': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `[' */ + cont++; +#if LUA_COMPAT_LSTR == 1 + if (sep == 0) + luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); +#endif + } + break; + } +#endif + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `]' */ +#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 + cont--; + if (sep == 0 && cont >= 0) break; +#endif + goto endloop; + } + break; + } + case '\n': + case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); + while (ls->current != del) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, "unfinished string", TK_EOS); + continue; /* to avoid warnings */ + case '\n': + case '\r': + luaX_lexerror(ls, "unfinished string", TK_STRING); + continue; /* to avoid warnings */ + case '\\': { + int c; + next(ls); /* do not save the `\' */ + switch (ls->current) { + case 'a': c = '\a'; break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + case '\n': /* go through */ + case '\r': save(ls, '\n'); inclinenumber(ls); continue; + case EOZ: continue; /* will raise an error next loop */ + default: { + if (!isdigit(ls->current)) + save_and_next(ls); /* handles \\, \", \', and \? */ + else { /* \xxx */ + int i = 0; + c = 0; + do { + c = 10*c + (ls->current-'0'); + next(ls); + } while (++i<3 && isdigit(ls->current)); + if (c > UCHAR_MAX) + luaX_lexerror(ls, "escape sequence too large", TK_STRING); + save(ls, c); + } + continue; + } + } + save(ls, c); + next(ls); + continue; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': + case '\r': { + inclinenumber(ls); + continue; + } + case '-': { + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* long comment */ + luaZ_resetbuffer(ls->buff); + continue; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); + continue; + } + case '[': { + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) return '['; + else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': { + next(ls); + if (ls->current != '=') return '='; + else { next(ls); return TK_EQ; } + } + case '<': { + next(ls); + if (ls->current != '=') return '<'; + else { next(ls); return TK_LE; } + } + case '>': { + next(ls); + if (ls->current != '=') return '>'; + else { next(ls); return TK_GE; } + } + case '~': { + next(ls); + if (ls->current != '=') return '~'; + else { next(ls); return TK_NE; } + } + case '"': + case '\'': { + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { + save_and_next(ls); + if (check_next(ls, ".")) { + if (check_next(ls, ".")) + return TK_DOTS; /* ... */ + else return TK_CONCAT; /* .. */ + } + else if (!isdigit(ls->current)) return '.'; + else { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + } + case EOZ: { + return TK_EOS; + } + default: { + if (isspace(ls->current)) { + lua_assert(!currIsNewline(ls)); + next(ls); + continue; + } + else if (isdigit(ls->current)) { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + else if (isalpha(ls->current) || ls->current == '_') { + /* identifier or reserved word */ + TString *ts; + do { + save_and_next(ls); + } while (isalnum(ls->current) || ls->current == '_'); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + if (ts->tsv.reserved > 0) /* reserved word? */ + return ts->tsv.reserved - 1 + FIRST_RESERVED; + else { + seminfo->ts = ts; + return TK_NAME; + } + } + else { + int c = ls->current; + next(ls); + return c; /* single-char tokens (+ - / ...) */ + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +void luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); +} + === added file 'lua/llex.h' --- lua/llex.h 1970-01-01 00:00:00 +0000 +++ lua/llex.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,81 @@ +/* +** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + +/* maximum length of a reserved word */ +#define TOKEN_LEN (sizeof("function")/sizeof(char)) + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, + TK_NAME, TK_STRING, TK_EOS +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +/* array with token `names' */ +LUAI_DATA const char *const luaX_tokens []; + + +typedef union { + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* `FuncState' is private to the parser */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + TString *source; /* current source name */ + char decpoint; /* locale decimal point */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC void luaX_lookahead (LexState *ls); +LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); +LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif === added file 'lua/llimits.h' --- lua/llimits.h 1970-01-01 00:00:00 +0000 +++ lua/llimits.h 2008-08-01 15:27:27 +0000 @@ -0,0 +1,136 @@ +/* +** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ +** Limits, basic types, and some other `installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#ifndef USE_GRUB_LIB +#include +#include +#endif /* ! USE_GRUB_LIB */ + + +#include "lua.h" + + +typedef LUAI_UINT32 lu_int32; + +typedef LUAI_UMEM lu_mem; + +typedef LUAI_MEM l_mem; + + + +/* chars used as small naturals (so that `char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to integer +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) + + + +/* type to ensure maximum alignment */ +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; + + +/* result of a `usual argument conversion' over lua_Number */ +typedef LUAI_UACNUMBER l_uacNumber; + + +/* internal assertions for in-house debugging */ +#ifdef lua_assert + +#define check_exp(c,e) (lua_assert(c), (e)) +#define api_check(l,e) lua_assert(e) + +#else + +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define api_check luai_apicheck + +#endif + + +#ifdef USE_GRUB_LIB +/* Redefine UNUSED: GRUB uses it as an attribute within the parameter + list, but LUA uses it as a statement in the function body. */ +#undef UNUSED +#endif /* USE_GRUB_LIB */ + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +#ifndef cast +#define cast(t, exp) ((t)(exp)) +#endif + +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) + + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef lu_int32 Instruction; + + + +/* maximum stack for a Lua function */ +#define MAXSTACK 250 + + + +/* minimum size for the string table (must be power of 2) */ +#ifndef MINSTRTABSIZE +#define MINSTRTABSIZE 32 +#endif + + +/* minimum size for string buffer */ +#ifndef LUA_MINBUFFER +#define LUA_MINBUFFER 32 +#endif + + +#ifndef lua_lock +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +#ifndef luai_threadyield +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#ifndef HARDSTACKTESTS +#define condhardstacktests(x) ((void)0) +#else +#define condhardstacktests(x) x +#endif + +#endif === added file 'lua/lmathlib.c' --- lua/lmathlib.c 1970-01-01 00:00:00 +0000 +++ lua/lmathlib.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,267 @@ +/* +** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define lmathlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (3.14159265358979323846) +#define RADIANS_PER_DEGREE (PI/180.0) + + + +static int math_abs (lua_State *L) { + lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, sin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, cos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, tan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, asin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, acos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_pushnumber(L, atan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan2 (lua_State *L) { + lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_ceil (lua_State *L) { + lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + return 1; +} + +static int math_floor (lua_State *L) { + lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + return 1; +} + +static int math_fmod (lua_State *L) { + lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_modf (lua_State *L) { + double ip; + double fp = modf(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; +} + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_log (lua_State *L) { + lua_pushnumber(L, log(luaL_checknumber(L, 1))); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, log10(luaL_checknumber(L, 1))); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, exp(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); + return 1; +} + + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + + +static int math_random (lua_State *L) { + /* the `%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ + lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: { /* only upper limit */ + int u = luaL_checkint(L, 1); + luaL_argcheck(L, 1<=u, 1, "interval is empty"); + lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ + break; + } + case 2: { /* lower and upper limits */ + int l = luaL_checkint(L, 1); + int u = luaL_checkint(L, 2); + luaL_argcheck(L, l<=u, 2, "interval is empty"); + lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + return 1; +} + + +static int math_randomseed (lua_State *L) { + srand(luaL_checkint(L, 1)); + return 0; +} + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan2", math_atan2}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cosh", math_cosh}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sinh", math_sinh}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tanh", math_tanh}, + {"tan", math_tan}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUALIB_API int luaopen_math (lua_State *L) { + luaL_register(L, LUA_MATHLIBNAME, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); +#if !defined LUA_NUMBER_INTEGRAL + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); +#endif +#if defined(LUA_COMPAT_MOD) + lua_getfield(L, -1, "fmod"); + lua_setfield(L, -2, "mod"); +#endif + return 1; +} + === added file 'lua/lmem.c' --- lua/lmem.c 1970-01-01 00:00:00 +0000 +++ lua/lmem.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,88 @@ +/* +** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lmem_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** (`osize' is the old size, `nsize' is the new size) +** +** Lua ensures that (ptr == NULL) iff (osize == 0). +** +** * frealloc(ud, NULL, 0, x) creates a new block of size `x' +** +** * frealloc(ud, p, x, 0) frees the block `p' +** (in this specific case, frealloc must return NULL). +** particularly, frealloc(ud, NULL, 0, 0) does nothing +** (which is equivalent to free(NULL) in ANSI C) +** +** frealloc returns NULL if it cannot create or reallocate the area +** (any reallocation to an equal or smaller size cannot fail!) +*/ + + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *errormsg) { + void *newblock; + int newsize; + if (*size >= limit/2) { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, errormsg); + newsize = limit; /* still have at least one free place */ + } + else { + newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +void *luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); + return NULL; /* to avoid warnings */ +} + + + +/* +** generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + block = (*g->frealloc)(g->ud, block, osize, nsize); + if (block == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + lua_assert((nsize == 0) == (block == NULL)); + g->totalbytes = (g->totalbytes - osize) + nsize; + return block; +} + === added file 'lua/lmem.h' --- lua/lmem.h 1970-01-01 00:00:00 +0000 +++ lua/lmem.h 2008-08-01 15:27:27 +0000 @@ -0,0 +1,51 @@ +/* +** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#include "llimits.h" +#include "lua.h" + +#define MEMERRMSG "not enough memory" + + +#define luaM_reallocv(L,b,on,n,e) \ + ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ + luaM_toobig(L)) + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) + +#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) + + +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_toobig (lua_State *L); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *errormsg); + +#endif + === added file 'lua/loadlib.c' --- lua/loadlib.c 1970-01-01 00:00:00 +0000 +++ lua/loadlib.c 2008-08-01 15:19:23 +0000 @@ -0,0 +1,664 @@ +/* +** $Id: loadlib.c,v 1.52.1.2 2007/12/28 14:58:43 roberto Exp $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Darwin (Mac OS X), an +** implementation for Windows, and a stub for other systems. +*/ + + +#include +#include + + +#define loadlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +#define LIBPREFIX "LOADLIB: " + +#define POF LUA_POF +#define LIB_FAIL "open" + + +/* error codes for ll_loadfunc */ +#define ERRLIB 1 +#define ERRFUNC 2 + +#define setprogdir(L) ((void)0) + + +static void ll_unloadlib (void *lib); +static void *ll_load (lua_State *L, const char *path); +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); + + + +#if defined(LUA_DL_DLOPEN) +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +static void ll_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + void *lib = dlopen(path, RTLD_NOW); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#include + + +#undef setprogdir + +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void ll_unloadlib (void *lib) { + FreeLibrary((HINSTANCE)lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + HINSTANCE lib = LoadLibraryA(path); + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DYLD) +/* +** {====================================================================== +** Native Mac OS X / Darwin Implementation +** ======================================================================= +*/ + +#include + + +/* Mac appends a `_' before C function names */ +#undef POF +#define POF "_" LUA_POF + + +static void pusherror (lua_State *L) { + const char *err_str; + const char *err_file; + NSLinkEditErrors err; + int err_num; + NSLinkEditError(&err, &err_num, &err_file, &err_str); + lua_pushstring(L, err_str); +} + + +static const char *errorfromcode (NSObjectFileImageReturnCode ret) { + switch (ret) { + case NSObjectFileImageInappropriateFile: + return "file is not a bundle"; + case NSObjectFileImageArch: + return "library is for wrong CPU type"; + case NSObjectFileImageFormat: + return "bad format"; + case NSObjectFileImageAccess: + return "cannot access file"; + case NSObjectFileImageFailure: + default: + return "unable to load library"; + } +} + + +static void ll_unloadlib (void *lib) { + NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); +} + + +static void *ll_load (lua_State *L, const char *path) { + NSObjectFileImage img; + NSObjectFileImageReturnCode ret; + /* this would be a rare case, but prevents crashing if it happens */ + if(!_dyld_present()) { + lua_pushliteral(L, "dyld not present"); + return NULL; + } + ret = NSCreateObjectFileImageFromFile(path, &img); + if (ret == NSObjectFileImageSuccess) { + NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | + NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage(img); + if (mod == NULL) pusherror(L); + return mod; + } + lua_pushstring(L, errorfromcode(ret)); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); + if (nss == NULL) { + lua_pushfstring(L, "symbol " LUA_QS " not found", sym); + return NULL; + } + return (lua_CFunction)NSAddressOfSymbol(nss); +} + +/* }====================================================== */ + + + +#else +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void ll_unloadlib (void *lib) { + (void)lib; /* to avoid warnings */ +} + + +static void *ll_load (lua_State *L, const char *path) { + (void)path; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + (void)lib; (void)sym; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif + + + +static void **ll_register (lua_State *L, const char *path) { + void **plib; + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ + if (!lua_isnil(L, -1)) /* is there an entry? */ + plib = (void **)lua_touserdata(L, -1); + else { /* no entry yet; create one */ + lua_pop(L, 1); + plib = (void **)lua_newuserdata(L, sizeof(const void *)); + *plib = NULL; + luaL_getmetatable(L, "_LOADLIB"); + lua_setmetatable(L, -2); + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_pushvalue(L, -2); + lua_settable(L, LUA_REGISTRYINDEX); + } + return plib; +} + + +/* +** __gc tag method: calls library's `ll_unloadlib' function with the lib +** handle +*/ +static int gctm (lua_State *L) { + void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); + if (*lib) ll_unloadlib(*lib); + *lib = NULL; /* mark library as closed */ + return 0; +} + + +static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { + void **reg = ll_register(L, path); + if (*reg == NULL) *reg = ll_load(L, path); + if (*reg == NULL) + return ERRLIB; /* unable to load library */ + else { + lua_CFunction f = ll_sym(L, *reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); + return 0; /* return function */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +static const char *pushnexttemplate (lua_State *L, const char *path) { + const char *l; + while (*path == *LUA_PATHSEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATHSEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname) { + const char *path; + name = luaL_gsub(L, name, ".", LUA_DIRSEP); + lua_getfield(L, LUA_ENVIRONINDEX, pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + lua_pushliteral(L, ""); /* error accumulator */ + while ((path = pushnexttemplate(L, path)) != NULL) { + const char *filename; + filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + lua_concat(L, 2); /* add entry to possible error message */ + } + return NULL; /* not found */ +} + + +static void loaderror (lua_State *L, const char *filename) { + luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int loader_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path"); + if (filename == NULL) return 1; /* library not found in this path */ + if (luaL_loadfile(L, filename) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static const char *mkfuncname (lua_State *L, const char *modname) { + const char *funcname; + const char *mark = strchr(modname, *LUA_IGMARK); + if (mark) modname = mark + 1; + funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); + funcname = lua_pushfstring(L, POF"%s", funcname); + lua_remove(L, -2); /* remove 'gsub' result */ + return funcname; +} + + +static int loader_C (lua_State *L) { + const char *funcname; + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath"); + if (filename == NULL) return 1; /* library not found in this path */ + funcname = mkfuncname(L, name); + if (ll_loadfunc(L, filename, funcname) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static int loader_Croot (lua_State *L) { + const char *funcname; + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath"); + if (filename == NULL) return 1; /* root not found */ + funcname = mkfuncname(L, name); + if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { + if (stat != ERRFUNC) loaderror(L, filename); /* real error */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; /* function not found */ + } + return 1; +} + + +static int loader_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_ENVIRONINDEX, "preload"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.preload") " must be a table"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; +} + + +static const int sentinel_ = 0; +#define sentinel ((void *)&sentinel_) + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + int i; + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); + if (lua_toboolean(L, -1)) { /* is it there? */ + if (lua_touserdata(L, -1) == sentinel) /* check loops */ + luaL_error(L, "loop or previous error loading module " LUA_QS, name); + return 1; /* package is already loaded */ + } + /* else must load it; iterate over available loaders */ + lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.loaders") " must be a table"); + lua_pushliteral(L, ""); /* error message accumulator */ + for (i=1; ; i++) { + lua_rawgeti(L, -2, i); /* get a loader */ + if (lua_isnil(L, -1)) + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -2)); + lua_pushstring(L, name); + lua_call(L, 1, 1); /* call it */ + if (lua_isfunction(L, -1)) /* did it find module? */ + break; /* module loaded successfully */ + else if (lua_isstring(L, -1)) /* loader returned error message? */ + lua_concat(L, 2); /* accumulate it */ + else + lua_pop(L, 1); + } + lua_pushlightuserdata(L, sentinel); + lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ + lua_pushstring(L, name); /* pass name as argument to module */ + lua_call(L, 1, 1); /* run loaded module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } + return 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** 'module' function +** ======================================================= +*/ + + +static void setfenv (lua_State *L) { + lua_Debug ar; + lua_getstack(L, 1, &ar); + lua_getinfo(L, "f", &ar); + lua_pushvalue(L, -2); + lua_setfenv(L, -2); + lua_pop(L, 1); +} + + +static void dooptions (lua_State *L, int n) { + int i; + for (i = 2; i <= n; i++) { + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } +} + + +static void modinit (lua_State *L, const char *modname) { + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) + return luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ + } + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + setfenv(L); + dooptions(L, loaded - 1); + return 0; +} + + +static int ll_seeall (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} + + +/* }====================================================== */ + + + +/* auxiliary mark (for internal use) */ +#define AUXMARK "\1" + +static void setpath (lua_State *L, const char *fieldname, const char *envname, + const char *def) { + const char *path = getenv(envname); + if (path == NULL) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, + LUA_PATHSEP AUXMARK LUA_PATHSEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); +} + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"seeall", ll_seeall}, + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { + {"module", ll_module}, + {"require", ll_require}, + {NULL, NULL} +}; + + +static const lua_CFunction loaders[] = + {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; + + +LUALIB_API int luaopen_package (lua_State *L) { + int i; + /* create new type _LOADLIB */ + luaL_newmetatable(L, "_LOADLIB"); + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); + /* create `package' table */ + luaL_register(L, LUA_LOADLIBNAME, pk_funcs); +#if defined(LUA_COMPAT_LOADLIB) + lua_getfield(L, -1, "loadlib"); + lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); +#endif + lua_pushvalue(L, -1); + lua_replace(L, LUA_ENVIRONINDEX); + /* create `loaders' table */ + lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1); + /* fill it with pre-defined loaders */ + for (i=0; loaders[i] != NULL; i++) { + lua_pushcfunction(L, loaders[i]); + lua_rawseti(L, -2, i+1); + } + lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ + setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ + setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" + LUA_EXECDIR "\n" LUA_IGMARK); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + lua_newtable(L); + lua_setfield(L, -2, "preload"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_register(L, NULL, ll_funcs); /* open lib into global table */ + lua_pop(L, 1); + return 1; /* return 'package' table */ +} + === added file 'lua/lobject.c' --- lua/lobject.c 1970-01-01 00:00:00 +0000 +++ lua/lobject.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,216 @@ +/* +** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#ifndef USE_GRUB_LIB +#include +#include +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define lobject_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + + +const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; + + +/* +** converts an integer to a "floating point byte", represented as +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. +*/ +int luaO_int2fb (unsigned int x) { + int e = 0; /* expoent */ + while (x >= 16) { + x = (x+1) >> 1; + e++; + } + if (x < 8) return x; + else return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 31; + if (e == 0) return x; + else return ((x & 7)+8) << (e - 1); +} + + +int luaO_log2 (unsigned int x) { + static const lu_byte log_2[256] = { + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = -1; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; + +} + + +int luaO_rawequalObj (const TValue *t1, const TValue *t2) { + if (ttype(t1) != ttype(t2)) return 0; + else switch (ttype(t1)) { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2); + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } +} + + +int luaO_str2d (const char *s, lua_Number *result) { + char *endptr; + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* conversion failed */ + if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ + *result = cast_num(strtoul(s, &endptr, 16)); + if (*endptr == '\0') return 1; /* most common case */ + while (isspace(cast(unsigned char, *endptr))) endptr++; + if (*endptr != '\0') return 0; /* invalid trailing characters? */ + return 1; +} + + + +static void pushstr (lua_State *L, const char *str) { + setsvalue2s(L, L->top, luaS_new(L, str)); + incr_top(L); +} + + +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 1; + pushstr(L, ""); + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); + incr_top(L); + switch (*(e+1)) { + case 's': { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s); + break; + } + case 'c': { + char buff[2]; + buff[0] = cast(char, va_arg(argp, int)); + buff[1] = '\0'; + pushstr(L, buff); + break; + } + case 'd': { + setnvalue(L->top, cast_num(va_arg(argp, int))); + incr_top(L); + break; + } + case 'f': { + setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); + incr_top(L); + break; + } + case 'p': { + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ + sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff); + break; + } + case '%': { + pushstr(L, "%"); + break; + } + default: { + char buff[3]; + buff[0] = '%'; + buff[1] = *(e+1); + buff[2] = '\0'; + pushstr(L, buff); + break; + } + } + n += 2; + fmt = e+2; + } + pushstr(L, fmt); + luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); + L->top -= n; + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +void luaO_chunkid (char *out, const char *source, size_t bufflen) { + if (*source == '=') { + strncpy(out, source+1, bufflen); /* remove first char */ + out[bufflen-1] = '\0'; /* ensures null termination */ + } + else { /* out = "source", or "...source" */ + if (*source == '@') { + size_t l; + source++; /* skip the `@' */ + bufflen -= sizeof(" '...' "); + l = strlen(source); + strcpy(out, ""); + if (l > bufflen) { + source += (l-bufflen); /* get last part of file name */ + strcat(out, "..."); + } + strcat(out, source); + } + else { /* out = [string "string"] */ + size_t len = strcspn(source, "\n\r"); /* stop at first newline */ + bufflen -= sizeof(" [string \"...\"] "); + if (len > bufflen) len = bufflen; + strcpy(out, "[string \""); + if (source[len] != '\0') { /* must truncate? */ + strncat(out, source, len); + strcat(out, "..."); + } + else + strcat(out, source); + strcat(out, "\"]"); + } + } +} === added file 'lua/lobject.h' --- lua/lobject.h 1970-01-01 00:00:00 +0000 +++ lua/lobject.h 2008-08-01 15:27:27 +0000 @@ -0,0 +1,383 @@ +/* +** $Id: lobject.h,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + + +#include "llimits.h" +#include "lua.h" + + +/* tags for values visible from Lua */ +#define LAST_TAG LUA_TTHREAD + +#define NUM_TAGS (LAST_TAG+1) + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO (LAST_TAG+1) +#define LUA_TUPVAL (LAST_TAG+2) +#define LUA_TDEADKEY (LAST_TAG+3) + + +/* +** Union of all collectable objects +*/ +typedef union GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common header in struct form +*/ +typedef struct GCheader { + CommonHeader; +} GCheader; + + + + +/* +** Union of all Lua values +*/ +typedef union { + GCObject *gc; + void *p; + lua_Number n; + int b; +} Value; + + +/* +** Tagged Values +*/ + +#define TValuefields Value value; int tt + +typedef struct lua_TValue { + TValuefields; +} TValue; + + +/* Macros to test type */ +#define ttisnil(o) (ttype(o) == LUA_TNIL) +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) +#define ttisstring(o) (ttype(o) == LUA_TSTRING) +#define ttistable(o) (ttype(o) == LUA_TTABLE) +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) +#define ttisthread(o) (ttype(o) == LUA_TTHREAD) +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) + +/* Macros to access values */ +#define ttype(o) ((o)->tt) +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) +#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + +/* +** for internal debug only +*/ +#define checkconsistency(obj) \ + lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) + +#define checkliveness(g,obj) \ + lua_assert(!iscollectable(obj) || \ + ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) + + +/* Macros to set values */ +#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) + +#define setnvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } + +#define setpvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } + +#define setbvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } + +#define setsvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ + checkliveness(G(L),i_o); } + +#define setuvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ + checkliveness(G(L),i_o); } + +#define setthvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ + checkliveness(G(L),i_o); } + +#define setclvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ + checkliveness(G(L),i_o); } + +#define sethvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ + checkliveness(G(L),i_o); } + +#define setptvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ + checkliveness(G(L),i_o); } + + + + +#define setobj(L,obj1,obj2) \ + { const TValue *o2=(obj2); TValue *o1=(obj1); \ + o1->value = o2->value; o1->tt=o2->tt; \ + checkliveness(G(L),o1); } + + +/* +** different types of sets, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue +/* from table to same table */ +#define setobjt2t setobj +/* to table */ +#define setobj2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + +#define setttype(obj, tt) (ttype(obj) = (tt)) + + +#define iscollectable(o) (ttype(o) >= LUA_TSTRING) + + + +typedef TValue *StkId; /* index to stack elements */ + + +/* +** String headers for string table +*/ +typedef union TString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct { + CommonHeader; + lu_byte reserved; + unsigned int hash; + size_t len; + } tsv; +} TString; + + +#define getstr(ts) cast(const char *, (ts) + 1) +#define svalue(o) getstr(tsvalue(o)) + + + +typedef union Udata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct { + CommonHeader; + struct Table *metatable; + struct Table *env; + size_t len; + } uv; +} Udata; + + + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + TValue *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines */ + struct LocVar *locvars; /* information about local variables */ + TString **upvalues; /* upvalue names */ + TString *source; + int sizeupvalues; + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int linedefined; + int lastlinedefined; + GCObject *gclist; + lu_byte nups; /* number of upvalues */ + lu_byte numparams; + lu_byte is_vararg; + lu_byte maxstacksize; +} Proto; + + +/* masks for new-style vararg */ +#define VARARG_HASARG 1 +#define VARARG_ISVARARG 2 +#define VARARG_NEEDSARG 4 + + +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + + +/* +** Upvalues +*/ + +typedef struct UpVal { + CommonHeader; + TValue *v; /* points to stack or to its own value */ + union { + TValue value; /* the value (when closed) */ + struct { /* double linked list (when open) */ + struct UpVal *prev; + struct UpVal *next; + } l; + } u; +} UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ + struct Table *env + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) + + +/* +** Tables +*/ + +typedef union TKey { + struct { + TValuefields; + struct Node *next; /* for chaining */ + } nk; + TValue tvk; +} TKey; + + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

lsizenode)) + + +#define luaO_nilobject (&luaO_nilobject_) + +LUAI_DATA const TValue luaO_nilobject_; + +#define ceillog2(x) (luaO_log2((x)-1) + 1) + +LUAI_FUNC int luaO_log2 (unsigned int x); +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); +LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); + + +#endif + === added file 'lua/lopcodes.c' --- lua/lopcodes.c 1970-01-01 00:00:00 +0000 +++ lua/lopcodes.c 2008-08-01 15:19:23 +0000 @@ -0,0 +1,102 @@ +/* +** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** See Copyright Notice in lua.h +*/ + + +#define lopcodes_c +#define LUA_CORE + + +#include "lopcodes.h" + + +/* ORDER OP */ + +const char *const luaP_opnames[NUM_OPCODES+1] = { + "MOVE", + "LOADK", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETGLOBAL", + "GETTABLE", + "SETGLOBAL", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "DIV", + "MOD", + "POW", + "UNM", + "NOT", + "LEN", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "FORPREP", + "TFORLOOP", + "SETLIST", + "CLOSE", + "CLOSURE", + "VARARG", + NULL +}; + + +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) + +const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ +}; + === added file 'lua/lopcodes.h' --- lua/lopcodes.h 1970-01-01 00:00:00 +0000 +++ lua/lopcodes.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,268 @@ +/* +** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + `A' : 8 bits + `B' : 9 bits + `C' : 9 bits + `Bx' : 18 bits (`B' and `C' together) + `sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 + +#define SIZE_OP 6 + +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) +*/ +#if SIZE_Bx < LUAI_BITSINT-1 +#define MAXARG_Bx ((1<>1) /* `sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + + +#define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) +#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ + ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ + ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ + ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) +#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ + ((cast(Instruction, b)< C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) =) R(A)*/ +OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ + +OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ +} OpCode; + + +#define NUM_OPCODES (cast(int, OP_VARARG) + 1) + + + +/*=========================================================================== + Notes: + (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, + and can be 0: OP_CALL then sets `top' to last_result+1, so + next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. + + (*) In OP_VARARG, if (B == 0) then use actual number of varargs and + set top (like in OP_CALL with C == 0). + + (*) In OP_RETURN, if (B == 0) then return up to `top' + + (*) In OP_SETLIST, if (B == 0) then B = `top'; + if (C == 0) then next `instruction' is real C + + (*) For comparisons, A specifies what condition the test should accept + (true or false). + + (*) All `skips' (pc++) assume that next instruction is a jump +===========================================================================*/ + + +/* +** masks for instruction properties. The format is: +** bits 0-1: op mode +** bits 2-3: C arg mode +** bits 4-5: B arg mode +** bit 6: instruction set register A +** bit 7: operator is a test +*/ + +enum OpArgMask { + OpArgN, /* argument is not used */ + OpArgU, /* argument is used */ + OpArgR, /* argument is a register or a jump offset */ + OpArgK /* argument is a constant or register/constant */ +}; + +LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) +#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) + + +LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + + +#endif === added file 'lua/loslib.c' --- lua/loslib.c 1970-01-01 00:00:00 +0000 +++ lua/loslib.c 2008-08-01 15:21:04 +0000 @@ -0,0 +1,247 @@ +/* +** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define loslib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int os_pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static int os_execute (lua_State *L) { + lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); + return 1; +} + + +static int os_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + return os_pushresult(L, remove(filename) == 0, filename); +} + + +static int os_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return os_pushresult(L, rename(fromname, toname) == 0, fromname); +} + + +static int os_tmpname (lua_State *L) { + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; +} + + +static int os_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + +static int getboolfield (lua_State *L, const char *key) { + int res; + lua_getfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d) { + int res; + lua_getfield(L, -1, key); + if (lua_isnumber(L, -1)) + res = (int)lua_tointeger(L, -1); + else { + if (d < 0) + return luaL_error(L, "field " LUA_QS " missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + + +static int os_date (lua_State *L) { + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + struct tm *stm; + if (*s == '!') { /* UTC? */ + stm = gmtime(&t); + s++; /* skip `!' */ + } + else + stm = localtime(&t); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon+1); + setfield(L, "year", stm->tm_year+1900); + setfield(L, "wday", stm->tm_wday+1); + setfield(L, "yday", stm->tm_yday+1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else { + char cc[3]; + luaL_Buffer b; + cc[0] = '%'; cc[2] = '\0'; + luaL_buffinit(L, &b); + for (; *s; s++) { + if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ + luaL_addchar(&b, *s); + else { + size_t reslen; + char buff[200]; /* should be big enough for any conversion result */ + cc[1] = *(++s); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (lua_Number)t); + return 1; +} + + +#if !defined LUA_NUMBER_INTEGRAL +static int os_difftime (lua_State *L) { + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} +#endif + +/* }====================================================== */ + + +static int os_setlocale (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int os_exit (lua_State *L) { + exit(luaL_optint(L, 1, EXIT_SUCCESS)); +} + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, +#if !defined LUA_NUMBER_INTEGRAL + {"difftime", os_difftime}, +#endif + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUALIB_API int luaopen_os (lua_State *L) { + luaL_register(L, LUA_OSLIBNAME, syslib); + return 1; +} + === added file 'lua/lparser.c' --- lua/lparser.c 1970-01-01 00:00:00 +0000 +++ lua/lparser.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,1341 @@ +/* +** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lparser_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) + +#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int breaklist; /* list of jumps out of this loop */ + lu_byte nactvar; /* # active locals outside the breakable structure */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isbreakable; /* true if `block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void chunk (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static void anchor_token (LexState *ls) { + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } +} + + +static void error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); +} + + +static void errorlimit (FuncState *fs, int limit, const char *what) { + const char *msg = (fs->f->linedefined == 0) ? + luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : + luaO_pushfstring(fs->L, "function at line %d has more than %d %s", + fs->f->linedefined, limit, what); + luaX_lexerror(fs->ls, msg, 0); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + LUA_QS " expected (to close " LUA_QS " at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.s.info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname(LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +static int registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "too many local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; +} + + +#define new_localvarliteral(ls,v,n) \ + new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) + + +static void new_localvar (LexState *ls, TString *name, int n) { + FuncState *fs = ls->fs; + luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); + fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; + } +} + + +static void removevars (LexState *ls, int tolevel) { + FuncState *fs = ls->fs; + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar).endpc = fs->pc; +} + + +static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { + int i; + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + for (i=0; inups; i++) { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { + lua_assert(f->upvalues[i] == name); + return i; + } + } + /* new one */ + luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); + luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, + TString *, MAX_INT, ""); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; + f->upvalues[f->nups] = name; + luaC_objbarrier(fs->L, f, name); + lua_assert(v->k == VLOCAL || v->k == VUPVAL); + fs->upvalues[f->nups].k = cast_byte(v->k); + fs->upvalues[f->nups].info = cast_byte(v->u.s.info); + return f->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i=fs->nactvar-1; i >= 0; i--) { + if (n == getlocvar(fs, i).varname) + return i; + } + return -1; /* not found */ +} + + +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl && bl->nactvar > level) bl = bl->previous; + if (bl) bl->upval = 1; +} + + +static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) { /* no more levels? */ + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ + return VGLOBAL; + } + else { + int v = searchvar(fs, n); /* look up at current level */ + if (v >= 0) { + init_exp(var, VLOCAL, v); + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else { /* not found at current level; try upper one */ + if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) + return VGLOBAL; + var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ + var->k = VUPVAL; /* upvalue in this level */ + return VUPVAL; + } + } +} + + +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VGLOBAL) + var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra-1); + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } +} + + +static void enterlevel (LexState *ls) { + if (++ls->L->nCcalls > LUAI_MAXCCALLS) + luaX_lexerror(ls, "chunk has too many syntax levels", 0); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { + bl->breaklist = NO_JUMP; + bl->isbreakable = isbreakable; + bl->nactvar = fs->nactvar; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + fs->bl = bl->previous; + removevars(fs->ls, bl->nactvar); + if (bl->upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + /* a block either controls scope or breaks (never both) */ + lua_assert(!bl->isbreakable || !bl->upval); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + luaK_patchtohere(fs, bl->breaklist); +} + + +static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizep; + int i; + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + f->p[fs->np++] = func->f; + luaC_objbarrier(ls->L, f, func->f); + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); + for (i=0; if->nups; i++) { + OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); + } +} + + +static void open_func (LexState *ls, FuncState *fs) { + lua_State *L = ls->L; + Proto *f = luaF_newproto(L); + fs->f = f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + fs->L = L; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = -1; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->bl = NULL; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + fs->h = luaH_new(L, 0, 0); + /* anchor table of constants and prototype (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + setptvalue2s(L, L->top, f); + incr_top(L); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + removevars(ls, 0); + luaK_ret(fs, 0, 0); /* final return */ + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); + f->sizeupvalues = f->nups; + lua_assert(luaG_checkcode(f)); + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + L->top -= 2; /* remove table and prototype from the stack */ + /* last token read was anchored in defunct function; must reanchor it */ + if (fs) anchor_token(ls); +} + + +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { + struct LexState lexstate; + struct FuncState funcstate; + lexstate.buff = buff; + luaX_setinput(L, &lexstate, z, luaS_new(L, name)); + open_func(&lexstate, &funcstate); + funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ + luaX_next(&lexstate); /* read first token */ + chunk(&lexstate); + check(&lexstate, TK_EOS); + close_func(&lexstate); + lua_assert(funcstate.prev == NULL); + lua_assert(funcstate.f->nups == 0); + lua_assert(lexstate.fs == NULL); + return funcstate.f; +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +static void field (LexState *ls, expdesc *v) { + /* field -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyreg(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) { + luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); + } +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + expr(ls, &cc->v); + luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> ?? */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + switch(ls->t.token) { + case TK_NAME: { /* may be listfields or recfields */ + luaX_lookahead(ls); + if (ls->lookahead.token != '=') /* expression? */ + listfield(ls, &cc); + else + recfield(ls, &cc); + break; + } + case '[': { /* constructor_item -> recfield */ + recfield(ls, &cc); + break; + } + default: { /* constructor_part -> listfield */ + listfield(ls, &cc); + break; + } + } + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { /* param -> NAME */ + new_localvar(ls, str_checkname(ls), nparams++); + break; + } + case TK_DOTS: { /* param -> `...' */ + luaX_next(ls); +#if defined(LUA_COMPAT_VARARG) + /* use `arg' as default name */ + new_localvarliteral(ls, "arg", nparams++); + f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; +#endif + f->is_vararg |= VARARG_ISVARARG; + break; + } + default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int needself, int line) { + /* body -> `(' parlist `)' chunk END */ + FuncState new_fs; + open_func(ls, &new_fs); + new_fs.f->linedefined = line; + checknext(ls, '('); + if (needself) { + new_localvarliteral(ls, "self", 0); + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + chunk(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + close_func(ls); + pushclosure(ls, &new_fs, e); +} + + +static int explist1 (LexState *ls, expdesc *v) { + /* explist1 -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) { + case '(': { /* funcargs -> `(' [ explist1 ] `)' */ + if (line != ls->lastline) + luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist1(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + return; + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.s.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void prefixexp (LexState *ls, expdesc *v) { + /* prefixexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + return; + } + } +} + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> + prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + prefixexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* field */ + field(ls, v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyreg(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | + constructor | FUNCTION body | primaryexp */ + switch (ls->t.token) { + case TK_NUMBER: { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use " LUA_QL("...") " outside a vararg function"); + fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + primaryexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '/': return OPR_DIV; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ + {10, 9}, {5, 4}, /* power and concat (right associative) */ + {3, 3}, {3, 3}, /* equality and inequality */ + {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ + {2, 2}, {1, 1} /* logical (and/or) */ +}; + +#define UNARY_PRIORITY 8 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where `binop' is any binary operator with a priority higher than `limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static int block_follow (int token) { + switch (token) { + case TK_ELSE: case TK_ELSEIF: case TK_END: + case TK_UNTIL: case TK_EOS: + return 1; + default: return 0; + } +} + + +static void block (LexState *ls) { + /* block -> chunk */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + chunk(ls); + lua_assert(bl.breaklist == NO_JUMP); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to a local variable, the local variable +** is needed in a previous assignment (to a table). If so, save original +** local value in a safe place and use this safe copy in the previous +** assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { + if (lh->v.k == VINDEXED) { + if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.info = extra; /* previous assignment will use safe copy */ + } + if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, + "syntax error"); + if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + primaryexp(ls, &nv.v); + if (nv.v.k == VLOCAL) + check_conflict(ls, lh, &nv.v); + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, + "variables in assignment"); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> `=' explist1 */ + int nexps; + checknext(ls, '='); + nexps = explist1(ls, &e); + if (nexps != nvars) { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void breakstat (LexState *ls) { + FuncState *fs = ls->fs; + BlockCnt *bl = fs->bl; + int upval = 0; + while (bl && !bl->isbreakable) { + upval |= bl->upval; + bl = bl->previous; + } + if (!bl) + luaX_syntaxerror(ls, "no loop to break"); + if (upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_patchlist(fs, luaK_jump(fs), whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + chunk(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (!bl2.upval) { /* no upvalues? */ + leaveblock(fs); /* finish scope */ + luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ + } + else { /* complete semantics when there are upvalues */ + breakstat(ls); /* if condition then break */ + luaK_patchtohere(ls->fs, condexit); /* else... */ + leaveblock(fs); /* finish scope... */ + luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ + } + leaveblock(fs); /* finish loop */ +} + + +static int exp1 (LexState *ls) { + expdesc e; + int k; + expr(ls, &e); + k = e.k; + luaK_exp2nextreg(ls->fs, &e); + return k; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)", 0); + new_localvarliteral(ls, "(for limit)", 1); + new_localvarliteral(ls, "(for step)", 2); + new_localvar(ls, varname, 3); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist1 forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 0; + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)", nvars++); + new_localvarliteral(ls, "(for state)", nvars++); + new_localvarliteral(ls, "(for control)", nvars++); + /* create declared variables */ + new_localvar(ls, indexname, nvars++); + while (testnext(ls, ',')) + new_localvar(ls, str_checkname(ls), nvars++); + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist1(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ +} + + +static int test_then_block (LexState *ls) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + int condexit; + luaX_next(ls); /* skip IF or ELSEIF */ + condexit = cond(ls); + checknext(ls, TK_THEN); + block(ls); /* `then' part */ + return condexit; +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int flist; + int escapelist = NO_JUMP; + flist = test_then_block(ls); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + flist = test_then_block(ls); /* ELSEIF cond THEN block */ + } + if (ls->t.token == TK_ELSE) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ + block(ls); /* `else' part */ + } + else + luaK_concat(fs, &escapelist, flist); + luaK_patchtohere(fs, escapelist); + check_match(ls, TK_END, TK_IF, line); +} + + +static void localfunc (LexState *ls) { + expdesc v, b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls), 0); + init_exp(&v, VLOCAL, fs->freereg); + luaK_reserveregs(fs, 1); + adjustlocalvars(ls, 1); + body(ls, &b, 0, ls->linenumber); + luaK_storevar(fs, &v, &b); + /* debug information will only see the variable after this point! */ + getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls), nvars++); + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist1(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {field} [`:' NAME] */ + int needself = 0; + singlevar(ls, v); + while (ls->t.token == '.') + field(ls, v); + if (ls->t.token == ':') { + needself = 1; + field(ls, v); + } + return needself; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int needself; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + needself = funcname(ls, &v); + body(ls, &b, needself, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + primaryexp(ls, &v.v); + if (v.v.k == VCALL) /* stat -> func */ + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + else { /* stat -> assignment */ + v.prev = NULL; + assignment(ls, &v, 1); + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN explist */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + luaX_next(ls); /* skip RETURN */ + if (block_follow(ls->t.token) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist1(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); +} + + +static int statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + switch (ls->t.token) { + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + return 0; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + return 0; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + return 0; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + return 0; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + return 0; + } + case TK_FUNCTION: { + funcstat(ls, line); /* stat -> funcstat */ + return 0; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + return 0; + } + case TK_RETURN: { /* stat -> retstat */ + retstat(ls); + return 1; /* must be last statement */ + } + case TK_BREAK: { /* stat -> breakstat */ + luaX_next(ls); /* skip BREAK */ + breakstat(ls); + return 1; /* must be last statement */ + } + default: { + exprstat(ls); + return 0; /* to avoid warnings */ + } + } +} + + +static void chunk (LexState *ls) { + /* chunk -> { stat [`;'] } */ + int islast = 0; + enterlevel(ls); + while (!islast && !block_follow(ls->t.token)) { + islast = statement(ls); + testnext(ls, ';'); + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + } + leavelevel(ls); +} + +/* }====================================================================== */ === added file 'lua/lparser.h' --- lua/lparser.h 1970-01-01 00:00:00 +0000 +++ lua/lparser.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,82 @@ +/* +** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in `upvalues' */ + VGLOBAL, /* info = index of table; aux = index of global name in `k' */ + VINDEXED, /* info = table register; aux = index register (or `k') */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VNONRELOC, /* info = result register */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ +} expkind; + +typedef struct expdesc { + expkind k; + union { + struct { int info, aux; } s; + lua_Number nval; + } u; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ +} expdesc; + + +typedef struct upvaldesc { + lu_byte k; + lu_byte info; +} upvaldesc; + + +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct lua_State *L; /* copy of the Lua state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* `pc' of last `jump target' */ + int jpc; /* list of pending jumps to `pc' */ + int freereg; /* first free register */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + short nlocvars; /* number of elements in `locvars' */ + lu_byte nactvar; /* number of active local variables */ + upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ + unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ +} FuncState; + + +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + const char *name); + + +#endif === added file 'lua/lstate.c' --- lua/lstate.c 1970-01-01 00:00:00 +0000 +++ lua/lstate.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,216 @@ +/* +** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lstate_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + lua_State l; + global_State g; +} LG; + + + +static void stack_init (lua_State *L1, lua_State *L) { + /* initialize CallInfo array */ + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); + L1->ci = L1->base_ci; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci - 1; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; + L1->top = L1->stack; + L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; + /* initialize first ci */ + L1->ci->func = L1->top; + setnilvalue(L1->top++); /* `function' entry for this `ci' */ + L1->base = L1->ci->base = L1->top; + L1->ci->top = L1->top + LUA_MINSTACK; +} + + +static void freestack (lua_State *L, lua_State *L1) { + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); + luaM_freearray(L, L1->stack, L1->stacksize, TValue); +} + + +/* +** open parts that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + luaS_fix(luaS_newliteral(L, MEMERRMSG)); + g->GCthreshold = 4*g->totalbytes; +} + + +static void preinit_state (lua_State *L, global_State *g) { + G(L) = g; + L->stack = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->size_ci = 0; + L->nCcalls = L->baseCcalls = 0; + L->status = 0; + L->base_ci = L->ci = NULL; + L->savedpc = NULL; + L->errfunc = 0; + setnilvalue(gt(L)); +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeall(L); /* collect all objects */ + lua_assert(g->rootgc == obj2gco(L)); + lua_assert(g->strt.nuse == 0); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); + luaZ_freebuffer(L, &g->buff); + freestack(L, L); + lua_assert(g->totalbytes == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); +} + + +lua_State *luaE_newthread (lua_State *L) { + lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); + luaC_link(L, obj2gco(L1), LUA_TTHREAD); + preinit_state(L1, G(L)); + stack_init(L1, L); /* init stack */ + setobj2n(L, gt(L1), gt(L)); /* share table of globals */ + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + lua_assert(iswhite(obj2gco(L1))); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L1); + freestack(L, L1); + luaM_freemem(L, fromstate(L1), state_size(lua_State)); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + void *l = (*f)(ud, NULL, 0, state_size(LG)); + if (l == NULL) return NULL; + L = tostate(l); + g = &((LG *)L)->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + set2bits(L->marked, FIXEDBIT, SFIXEDBIT); + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->GCthreshold = 0; /* mark it as unfinished state */ + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(registry(L)); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->gcstate = GCSpause; + g->rootgc = obj2gco(L); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->tmudata = NULL; + g->totalbytes = sizeof(LG); + g->gcpause = LUAI_GCPAUSE; + g->gcstepmul = LUAI_GCMUL; + g->gcdept = 0; + for (i=0; imt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + else + luai_userstateopen(L); + return L; +} + + +static void callallgcTM (lua_State *L, void *ud) { + UNUSED(ud); + luaC_callGCTM(L); /* call GC metamethods for all udata */ +} + + +LUA_API void lua_close (lua_State *L) { + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ + L->errfunc = 0; /* no error function during GC metamethods */ + do { /* repeat until no more errors */ + L->ci = L->base_ci; + L->base = L->top = L->ci->base; + L->nCcalls = L->baseCcalls = 0; + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); + lua_assert(G(L)->tmudata == NULL); + luai_userstateclose(L); + close_state(L); +} + === added file 'lua/lstate.h' --- lua/lstate.h 1970-01-01 00:00:00 +0000 +++ lua/lstate.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,169 @@ +/* +** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* table of globals */ +#define gt(L) (&L->l_gt) + +/* registry */ +#define registry(L) (&G(L)->l_registry) + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_CI_SIZE 8 + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + + +typedef struct stringtable { + GCObject **hash; + lu_int32 nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** informations about a call +*/ +typedef struct CallInfo { + StkId base; /* base for this function */ + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + const Instruction *savedpc; + int nresults; /* expected number of results from this function */ + int tailcalls; /* number of tail calls lost under this entry */ +} CallInfo; + + + +#define curr_func(L) (clvalue(L->ci->func)) +#define ci_func(ci) (clvalue((ci)->func)) +#define f_isLua(ci) (!ci_func(ci)->c.isC) +#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) + + +/* +** `global state', shared by all threads of this state +*/ +typedef struct global_State { + stringtable strt; /* hash table for strings */ + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to `frealloc' */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + int sweepstrgc; /* position of sweep in `strt' */ + GCObject *rootgc; /* list of all collectable objects */ + GCObject **sweepgc; /* position of sweep in `rootgc' */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of weak tables (to be cleared) */ + GCObject *tmudata; /* last element of list of userdata to be GC */ + Mbuffer buff; /* temporary buffer for string concatentation */ + lu_mem GCthreshold; + lu_mem totalbytes; /* number of bytes currently allocated */ + lu_mem estimate; /* an estimate of number of bytes actually in use */ + lu_mem gcdept; /* how much GC is `behind schedule' */ + int gcpause; /* size of pause between successive GCs */ + int gcstepmul; /* GC `granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + TValue l_registry; + struct lua_State *mainthread; + UpVal uvhead; /* head of double-linked list of all open upvalues */ + struct Table *mt[NUM_TAGS]; /* metatables for basic types */ + TString *tmname[TM_N]; /* array with tag-method names */ +} global_State; + + +/* +** `per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + StkId top; /* first free slot in the stack */ + StkId base; /* base of current function */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *savedpc; /* `savedpc' of current function */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + CallInfo *end_ci; /* points after end of ci array*/ + CallInfo *base_ci; /* array of CallInfo's */ + int stacksize; + int size_ci; /* size of array `base_ci' */ + unsigned short nCcalls; /* number of nested C calls */ + unsigned short baseCcalls; /* nested C calls when resuming coroutine */ + lu_byte hookmask; + lu_byte allowhook; + int basehookcount; + int hookcount; + lua_Hook hook; + TValue l_gt; /* table of globals */ + TValue env; /* temporary place for environments */ + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects +*/ +union GCObject { + GCheader gch; + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ +}; + + +/* macros to convert a GCObject into a specific value */ +#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) +#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define ngcotouv(o) \ + check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + +/* macro to convert any Lua object into a GCObject */ +#define obj2gco(v) (cast(GCObject *, (v))) + + +LUAI_FUNC lua_State *luaE_newthread (lua_State *L); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); + +#endif + === added file 'lua/lstring.c' --- lua/lstring.c 1970-01-01 00:00:00 +0000 +++ lua/lstring.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,113 @@ +/* +** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lstring_c +#define LUA_CORE + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + + +void luaS_resize (lua_State *L, int newsize) { + GCObject **newhash; + stringtable *tb; + int i; + if (G(L)->gcstate == GCSsweepstring) + return; /* cannot resize during GC traverse */ + newhash = luaM_newvector(L, newsize, GCObject *); + tb = &G(L)->strt; + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + while (p) { /* for each node in the list */ + GCObject *next = p->gch.next; /* save next */ + unsigned int h = gco2ts(p)->hash; + int h1 = lmod(h, newsize); /* new position */ + lua_assert(cast_int(h%newsize) == lmod(h, newsize)); + p->gch.next = newhash[h1]; /* chain it */ + newhash[h1] = p; + p = next; + } + } + luaM_freearray(L, tb->hash, tb->size, TString *); + tb->size = newsize; + tb->hash = newhash; +} + + +static TString *newlstr (lua_State *L, const char *str, size_t l, + unsigned int h) { + TString *ts; + stringtable *tb; + if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.marked = luaC_white(G(L)); + ts->tsv.tt = LUA_TSTRING; + ts->tsv.reserved = 0; + memcpy(ts+1, str, l*sizeof(char)); + ((char *)(ts+1))[l] = '\0'; /* ending 0 */ + tb = &G(L)->strt; + h = lmod(h, tb->size); + ts->tsv.next = tb->hash[h]; /* chain new entry */ + tb->hash[h] = obj2gco(ts); + tb->nuse++; + if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + return ts; +} + + +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + GCObject *o; + unsigned int h = cast(unsigned int, l); /* seed */ + size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ + size_t l1; + for (l1=l; l1>=step; l1-=step) /* compute hash */ + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); + for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; + o != NULL; + o = o->gch.next) { + TString *ts = rawgco2ts(o); + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { + /* string may be dead */ + if (isdead(G(L), o)) changewhite(o); + return ts; + } + } + return newlstr(L, str, l, h); /* not found */ +} + + +Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); + u->uv.marked = luaC_white(G(L)); /* is not finalized */ + u->uv.tt = LUA_TUSERDATA; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + /* chain it on udata list (after main thread) */ + u->uv.next = G(L)->mainthread->next; + G(L)->mainthread->next = obj2gco(u); + return u; +} + === added file 'lua/lstring.h' --- lua/lstring.h 1970-01-01 00:00:00 +0000 +++ lua/lstring.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,31 @@ +/* +** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) + +#define sizeudata(u) (sizeof(union Udata)+(u)->len) + +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) + +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); + + +#endif === added file 'lua/lstrlib.c' --- lua/lstrlib.c 1970-01-01 00:00:00 +0000 +++ lua/lstrlib.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,872 @@ +/* +** $Id: lstrlib.c,v 1.132.1.3 2007/12/28 15:32:23 roberto Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define lstrlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* macro to `unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, l); + return 1; +} + + +static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { + /* relative string position: negative means back from end */ + return (pos>=0) ? pos : (ptrdiff_t)len+pos+1; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; + if (start <= end) + lua_pushlstring(L, s+start-1, end-start+1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + while (l--) luaL_addchar(&b, s[l]); + luaL_pushresult(&b); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + for (i=0; i 0) + luaL_addlstring(&b, s, l); + luaL_pushresult(&b); + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi <= 0) posi = 1; + if ((size_t)pose > l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* overflow? */ + luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index"); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a `]' */ + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && *p != '\0') + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (int c, const char *p, const char *ep) { + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } +} + + +static const char *match (MatchState *ms, const char *s, const char *p); + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (*p == 0 || *(p+1) == 0) + luaL_error(ms->L, "unbalanced pattern"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (ssrc_end && singlematch(uchar(*s), p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + init: /* using goto's to optimize tail recursion */ + switch (*p) { + case '(': { /* start capture */ + if (*(p+1) == ')') /* position capture? */ + return start_capture(ms, s, p+2, CAP_POSITION); + else + return start_capture(ms, s, p+1, CAP_UNFINISHED); + } + case ')': { /* end capture */ + return end_capture(ms, s, p+1); + } + case L_ESC: { + switch (*(p+1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p+2); + if (s == NULL) return NULL; + p+=4; goto init; /* else return match(ms, s, p+4); */ + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s-1); + if (matchbracketclass(uchar(previous), p, ep-1) || + !matchbracketclass(uchar(*s), p, ep-1)) return NULL; + p=ep; goto init; /* else return match(ms, s, ep); */ + } + default: { + if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p+1))); + if (s == NULL) return NULL; + p+=2; goto init; /* else return match(ms, s, p+2) */ + } + goto dflt; /* case default */ + } + } + } + case '\0': { /* end of pattern */ + return s; /* match succeeded */ + } + case '$': { + if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ + return (s == ms->src_end) ? s : NULL; /* check end of string */ + else goto dflt; + } + default: dflt: { /* it is a pattern item */ + const char *ep = classend(ms, p); /* points to what is next */ + int m = ssrc_end && singlematch(uchar(*s), p, ep); + switch (*ep) { + case '?': { /* optional */ + const char *res; + if (m && ((res=match(ms, s+1, ep+1)) != NULL)) + return res; + p=ep+1; goto init; /* else return match(ms, s, ep+1); */ + } + case '*': { /* 0 or more repetitions */ + return max_expand(ms, s, p, ep); + } + case '+': { /* 1 or more repetitions */ + return (m ? max_expand(ms, s+1, p, ep) : NULL); + } + case '-': { /* 0 or more repetitions (minimum) */ + return min_expand(ms, s, p, ep); + } + default: { + if (!m) return NULL; + s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ + } + } + } + } +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + if (i >= ms->level) { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +static int str_find_aux (lua_State *L, int find) { + size_t l1, l2; + const char *s = luaL_checklstring(L, 1, &l1); + const char *p = luaL_checklstring(L, 2, &l2); + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; + if (init < 0) init = 0; + else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; + if (find && (lua_toboolean(L, 4) || /* explicit request? */ + strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ + /* do a plain search */ + const char *s2 = lmemfind(s+init, l1-init, p, l2); + if (s2) { + lua_pushinteger(L, s2-s+1); + lua_pushinteger(L, s2-s+l2); + return 2; + } + } + else { + MatchState ms; + int anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1=s+init; + ms.L = L; + ms.src_init = s; + ms.src_end = s+l1; + do { + const char *res; + ms.level = 0; + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, s1-s+1); /* start */ + lua_pushinteger(L, res-s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +static int gmatch_aux (lua_State *L) { + MatchState ms; + size_t ls; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tostring(L, lua_upvalueindex(2)); + const char *src; + ms.L = L; + ms.src_init = s; + ms.src_end = s+ls; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); + src <= ms.src_end; + src++) { + const char *e; + ms.level = 0; + if ((e = match(&ms, src, p)) != NULL) { + lua_Integer newstart = e-s; + if (e == src) newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static int gfind_nodef (lua_State *L) { + return luaL_error(L, LUA_QL("string.gfind") " was renamed to " + LUA_QL("string.gmatch")); +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) + luaL_addchar(b, news[i]); + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } +} + + +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + lua_State *L = ms->L; + switch (lua_type(L, 3)) { + case LUA_TNUMBER: + case LUA_TSTRING: { + add_s(ms, b, s, e); + return; + } + case LUA_TFUNCTION: { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + + +static int str_gsub (lua_State *L) { + size_t srcl; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); + int max_s = luaL_optint(L, 4, srcl+1); + int anchor = (*p == '^') ? (p++, 1) : 0; + int n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + ms.L = L; + ms.src_init = src; + ms.src_end = src+srcl; + while (n < max_s) { + const char *e; + ms.level = 0; + e = match(&ms, src, p); + if (e) { + n++; + add_value(&ms, &b, src, e); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* valid flags in a format specification */ +#define FLAGS "-+ #0" +/* +** maximum size of each format specification (such as '%-099.99d') +** (+10 accounts for %99.99x plus margin of error) +*/ +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) + + +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) { + switch (*s) { + case '"': case '\\': case '\n': { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + break; + } + case '\r': { + luaL_addlstring(b, "\\r", 2); + break; + } + case '\0': { + luaL_addlstring(b, "\\000", 4); + break; + } + default: { + luaL_addchar(b, *s); + break; + } + } + s++; + } + luaL_addchar(b, '"'); +} + +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + strncpy(form, strfrmt, p - strfrmt + 1); + form += p - strfrmt + 1; + *form = '\0'; + return p; +} + + +static void addintlen (char *form) { + size_t l = strlen(form); + char spec = form[l - 1]; + strcpy(form + l - 1, LUA_INTFRMLEN); + form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; + form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; +} + + +static int str_format (lua_State *L) { + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char buff[MAX_ITEM]; /* to store the formatted item */ + arg++; + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + sprintf(buff, form, (int)luaL_checknumber(L, arg)); + break; + } + case 'd': case 'i': { + addintlen(form); + sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'o': case 'u': case 'x': case 'X': { + addintlen(form); + sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } +#if !defined LUA_NUMBER_INTEGRAL + case 'e': case 'E': case 'f': + case 'g': case 'G': { + sprintf(buff, form, (double)luaL_checknumber(L, arg)); + break; + } +#endif + case 'q': { + addquoted(L, &b, arg); + continue; /* skip the 'addsize' at the end */ + } + case 's': { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + lua_pushvalue(L, arg); + luaL_addvalue(&b); + continue; /* skip the `addsize' at the end */ + } + else { + sprintf(buff, form, s); + break; + } + } + default: { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " + LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addlstring(&b, buff, strlen(buff)); + } + } + luaL_pushresult(&b); + return 1; +} + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gfind", gfind_nodef}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + lua_createtable(L, 0, 1); /* create metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); /* set string metatable */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* string library... */ + lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUALIB_API int luaopen_string (lua_State *L) { + luaL_register(L, LUA_STRLIBNAME, strlib); +#if defined(LUA_COMPAT_GFIND) + lua_getfield(L, -1, "gmatch"); + lua_setfield(L, -2, "gfind"); +#endif + createmetatable(L); + return 1; +} + === added file 'lua/ltable.c' --- lua/ltable.c 1970-01-01 00:00:00 +0000 +++ lua/ltable.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,590 @@ +/* +** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest `n' such that at +** least half the slots between 0 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#ifndef USE_GRUB_LIB +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define ltable_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "ltable.h" + + +/* +** max size of array part is 2^MAXBITS +*/ +#if LUAI_BITSINT > 26 +#define MAXBITS 26 +#else +#define MAXBITS (LUAI_BITSINT-2) +#endif + +#define MAXASIZE (1 << MAXBITS) + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t,p) hashpow2(t, p) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, IntPoint(p)) + + +/* +** number of ints inside a lua_Number +*/ +#define numints cast_int(sizeof(lua_Number)/sizeof(int)) + + + +#define dummynode (&dummynode_) + +static const Node dummynode_ = { + {{NULL}, LUA_TNIL}, /* value */ + {{{NULL}, LUA_TNIL, NULL}} /* key */ +}; + + +/* +** hash for lua_Numbers +*/ +static Node *hashnum (const Table *t, lua_Number n) { + unsigned int a[numints]; + int i; + if (luai_numeq(n, 0)) /* avoid problems with -0 */ + return gnode(t, 0); + memcpy(a, &n, sizeof(a)); + for (i = 1; i < numints; i++) a[0] += a[i]; + return hashmod(t, a[0]); +} + + + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +static Node *mainposition (const Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TSTRING: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex (const TValue *key) { + if (ttisnumber(key)) { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ +} + + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signalled by -1. +*/ +static int findindex (lua_State *L, Table *t, StkId key) { + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i-1; /* yes; that's the index (corrected to C) */ + else { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaO_rawequalObj(key2tval(n), key) || + (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && + gcvalue(gkey(n)) == gcvalue(key))) { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else n = gnext(n); + } while (n); + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + return 0; /* to avoid warnings */ + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setnvalue(key, cast_num(i+1)); + setobj2s(L, key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, key2tval(gnode(t, i))); + setobj2s(L, key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + + +static int computesizes (int nums[], int *narray) { + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { + if (nums[i] > 0) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) break; /* all elements already counted */ + } + *narray = n; + lua_assert(*narray/2 <= na && na <= *narray); + return na; +} + + +static int countint (const TValue *key, int *nums) { + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ + nums[ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +static int numusearray (const Table *t, int *nums) { + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) { + if (!ttisnil(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, int *nums, int *pnasize) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + ause += countint(key2tval(n), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; +} + + +static void setarrayvector (lua_State *L, Table *t, int size) { + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, int size) { + int lsize; + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; + } + else { + int i; + lsize = ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i=0; ilsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ +} + + +static void resize (lua_State *L, Table *t, int nasize, int nhsize) { + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) { + Node *old = nold+i; + if (!ttisnil(gval(old))) + setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); + } + if (nold != dummynode) + luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ +} + + +void luaH_resizearray (lua_State *L, Table *t, int nasize) { + int nsize = (t->node == dummynode) ? 0 : sizenode(t); + resize(L, t, nasize, nsize); +} + + +static void rehash (lua_State *L, Table *t, const TValue *ek) { + int nasize, na; + int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ + int i; + int totaluse; + for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + resize(L, t, nasize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L, int narray, int nhash) { + Table *t = luaM_new(L, Table); + luaC_link(L, obj2gco(t), LUA_TTABLE); + t->metatable = NULL; + t->flags = cast_byte(~0); + /* temporary values (kept only if some malloc fails) */ + t->array = NULL; + t->sizearray = 0; + t->lsizenode = 0; + t->node = cast(Node *, dummynode); + setarrayvector(L, t, narray); + setnodevector(L, t, nhash); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (t->node != dummynode) + luaM_freearray(L, t->node, sizenode(t), Node); + luaM_freearray(L, t->array, t->sizearray, TValue); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + while (t->lastfree-- > t->node) { + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static TValue *newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || mp == dummynode) { + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + return luaH_set(L, t, key); /* re-insert key into grown table */ + } + lua_assert(n != dummynode); + othern = mainposition(t, key2tval(mp)); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } + } + gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; + luaC_barriert(L, t, key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); +} + + +/* +** search function for integers +*/ +const TValue *luaH_getnum (Table *t, int key) { + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } +} + + +/* +** search function for strings +*/ +const TValue *luaH_getstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNIL: return luaO_nilobject; + case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNUMBER: { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ + return luaH_getnum(t, k); /* use specialized version */ + /* else go through */ + } + default: { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (luaO_rawequalObj(key2tval(n), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } + } +} + + +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { + const TValue *p = luaH_get(t, key); + t->flags = 0; + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + luaG_runerror(L, "table index is NaN"); + return newkey(L, t, key); + } +} + + +TValue *luaH_setnum (lua_State *L, Table *t, int key) { + const TValue *p = luaH_getnum(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setnvalue(&k, cast_num(key)); + return newkey(L, t, &k); + } +} + + +TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { + const TValue *p = luaH_getstr(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setsvalue(L, &k, key); + return newkey(L, t, &k); + } +} + + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getnum(t, j))) { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getnum(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getnum(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table `t'. A `boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (t->node == dummynode) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + + + +#if defined(LUA_DEBUG) + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainposition(t, key); +} + +int luaH_isdummy (Node *n) { return n == dummynode; } + +#endif === added file 'lua/ltable.h' --- lua/ltable.h 1970-01-01 00:00:00 +0000 +++ lua/ltable.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,40 @@ +/* +** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.nk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) + +#define key2tval(n) (&(n)->i_key.tvk) + + +LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); +LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (Node *n); +#endif + + +#endif === added file 'lua/ltablib.c' --- lua/ltablib.c 1970-01-01 00:00:00 +0000 +++ lua/ltablib.c 2008-08-01 15:19:23 +0000 @@ -0,0 +1,279 @@ +/* +** $Id: ltablib.c,v 1.38.1.2 2007/12/28 15:32:23 roberto Exp $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltablib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) + + +static int foreachi (lua_State *L) { + int i; + int n = aux_getn(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); + for (i=1; i <= n; i++) { + lua_pushvalue(L, 2); /* function */ + lua_pushinteger(L, i); /* 1st argument */ + lua_rawgeti(L, 1, i); /* 2nd argument */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 1); /* remove nil result */ + } + return 0; +} + + +static int foreach (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pushvalue(L, 2); /* function */ + lua_pushvalue(L, -3); /* key */ + lua_pushvalue(L, -3); /* value */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 2); /* remove value and result */ + } + return 0; +} + + +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; +} + + +static int getn (lua_State *L) { + lua_pushinteger(L, aux_getn(L, 1)); + return 1; +} + + +static int setn (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); +#ifndef luaL_setn + luaL_setn(L, 1, luaL_checkint(L, 2)); +#else + luaL_error(L, LUA_QL("setn") " is obsolete"); +#endif + lua_pushvalue(L, 1); + return 1; +} + + +static int tinsert (lua_State *L) { + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + if (pos > e) e = pos; /* `grow' array if necessary */ + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } + } + luaL_setn(L, 1, e); /* new size */ + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + int e = aux_getn(L, 1); + int pos = luaL_optint(L, 2, e); + if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ + return 0; /* nothing to remove */ + luaL_setn(L, 1, e - 1); /* t.n = n-1 */ + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ;pos= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j +#endif /* ! USE_GRUB_LIB */ + +#define ltm_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +const char *const luaT_typenames[] = { + "nil", "boolean", "userdata", "number", + "string", "table", "function", "userdata", "thread", + "proto", "upval" +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__eq", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__len", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttype(o)]; + } + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + === added file 'lua/ltm.h' --- lua/ltm.h 1970-01-01 00:00:00 +0000 +++ lua/ltm.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,54 @@ +/* +** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_MOD, + TM_POW, + TM_UNM, + TM_LEN, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +LUAI_DATA const char *const luaT_typenames[]; + + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +#endif === added file 'lua/lua.c' --- lua/lua.c 1970-01-01 00:00:00 +0000 +++ lua/lua.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,418 @@ +/* +** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua stand-alone interpreter +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#include + +#define STDERR_PRINTF(format, args...) fprintf(stderr, format, ##args) +#define STDERR_FLUSH() fflush(stderr) +#define PRINT(s) fputs(s, stdout) +#define FLUSH() fflush(stdout) +#define GETENV(name) getenv(name) + +#else /* USE_GRUB_LIB */ +#include "luacmd.h" +#define STDERR_PRINTF(format, args...) grub_printf(format, ##args) +#define STDERR_FLUSH() +#define PRINT(s) grub_printf("%s", s) +#define FLUSH() +#define GETENV(name) grub_env_get(name) + +#endif /* USE_GRUB_LIB */ + +#define lua_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static lua_State *globalL = NULL; + +static const char *progname = LUA_PROGNAME; + +#ifndef USE_GRUB_LIB +static void lstop (lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); + luaL_error(L, "interrupted!"); +} + + +static void laction (int i) { + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, + terminate process (default action) */ + lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); +} +#endif /* ! USE_GRUB_LIB */ + + +static void print_usage (void) { + STDERR_PRINTF( + "usage: %s [options] [script [args]].\n" + "Available options are:\n" + " -e stat execute string " LUA_QL("stat") "\n" + " -l name require library " LUA_QL("name") "\n" + " -i enter interactive mode after executing " LUA_QL("script") "\n" + " -v show version information\n" + " -- stop handling options\n" + " - execute stdin and stop handling options\n" + , + progname); + STDERR_FLUSH(); +} + + +static void l_message (const char *pname, const char *msg) { + if (pname) + STDERR_PRINTF("%s: ", pname); + STDERR_PRINTF("%s\n", msg); + STDERR_FLUSH(); +} + + +static int report (lua_State *L, int status) { + if (status && !lua_isnil(L, -1)) { + const char *msg = lua_tostring(L, -1); + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + } + return status; +} + + +static int traceback (lua_State *L) { + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; +} + + +static int docall (lua_State *L, int narg, int clear) { + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ +#ifndef USE_GRUB_LIB + signal(SIGINT, laction); +#endif /* ! USE_GRUB_LIB */ + status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); +#ifndef USE_GRUB_LIB + signal(SIGINT, SIG_DFL); +#endif /* ! USE_GRUB_LIB */ + lua_remove(L, base); /* remove traceback function */ + /* force a complete garbage collection in case of errors */ + if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); + return status; +} + + +static void print_version (void) { + l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); +} + + +static int getargs (lua_State *L, char **argv, int n) { + int narg; + int i; + int argc = 0; + while (argv[argc]) argc++; /* count total number of arguments */ + narg = argc - (n + 1); /* number of arguments to the script */ + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i=n+1; i < argc; i++) + lua_pushstring(L, argv[i]); + lua_createtable(L, narg, n + 1); + for (i=0; i < argc; i++) { + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, i - n); + } + return narg; +} + + +static int dofile (lua_State *L, const char *name) { + int status = luaL_loadfile(L, name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dostring (lua_State *L, const char *s, const char *name) { + int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dolibrary (lua_State *L, const char *name) { + lua_getglobal(L, "require"); + lua_pushstring(L, name); + return report(L, docall(L, 1, 1)); +} + + +static const char *get_prompt (lua_State *L, int firstline) { + const char *p; + lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); + p = lua_tostring(L, -1); + if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); + lua_pop(L, 1); /* remove global */ + return p; +} + + +static int incomplete (lua_State *L, int status) { + if (status == LUA_ERRSYNTAX) { + size_t lmsg; + const char *msg = lua_tolstring(L, -1, &lmsg); + const char *tp = msg + lmsg - (sizeof(LUA_QL("")) - 1); + if (strstr(msg, LUA_QL("")) == tp) { + lua_pop(L, 1); + return 1; + } + } + return 0; /* else... */ +} + + +static int pushline (lua_State *L, int firstline) { + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + if (lua_readline(L, b, prmt) == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ + b[l-1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; +} + + +static int loadline (lua_State *L) { + int status; + lua_settop(L, 0); + if (!pushline(L, 1)) + return -1; /* no input */ + for (;;) { /* repeat until gets a complete line */ + status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + if (!incomplete(L, status)) break; /* cannot try to add lines? */ + if (!pushline(L, 0)) /* no more input? */ + return -1; + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + lua_saveline(L, 1); + lua_remove(L, 1); /* remove line */ + return status; +} + + +static void dotty (lua_State *L) { + int status; + const char *oldprogname = progname; + progname = NULL; + while ((status = loadline(L)) != -1) { + if (status == 0) status = docall(L, 0, 0); + report(L, status); + if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) + l_message(progname, lua_pushfstring(L, + "error calling " LUA_QL("print") " (%s)", + lua_tostring(L, -1))); + } + } + lua_settop(L, 0); /* clear stack */ + PRINT("\n"); + FLUSH(); + progname = oldprogname; +} + + +static int handle_script (lua_State *L, char **argv, int n) { + int status; + const char *fname; + int narg = getargs(L, argv, n); /* collect arguments */ + lua_setglobal(L, "arg"); + fname = argv[n]; + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + lua_insert(L, -(narg+1)); + if (status == 0) + status = docall(L, narg, 0); + else + lua_pop(L, narg); + return report(L, status); +} + + +/* check that argument has no extra characters at the end */ +#define notail(x) {if ((x)[2] != '\0') return -1;} + + +static int collectargs (char **argv, int *pi, int *pv, int *pe) { + int i; + for (i = 1; argv[i] != NULL; i++) { + if (argv[i][0] != '-') /* not an option? */ + return i; + switch (argv[i][1]) { /* option */ + case '-': + notail(argv[i]); + return (argv[i+1] != NULL ? i+1 : 0); + case '\0': + return i; + case 'i': + notail(argv[i]); + *pi = 1; /* go through */ + case 'v': + notail(argv[i]); + *pv = 1; + break; + case 'e': + *pe = 1; /* go through */ + case 'l': + if (argv[i][2] == '\0') { + i++; + if (argv[i] == NULL) return -1; + } + break; + default: return -1; /* invalid option */ + } + } + return 0; +} + + +static int runargs (lua_State *L, char **argv, int n) { + int i; + for (i = 1; i < n; i++) { + if (argv[i] == NULL) continue; + lua_assert(argv[i][0] == '-'); + switch (argv[i][1]) { /* option */ + case 'e': { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') chunk = argv[++i]; + lua_assert(chunk != NULL); + if (dostring(L, chunk, "=(command line)") != 0) + return 1; + break; + } + case 'l': { + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + lua_assert(filename != NULL); + if (dolibrary(L, filename)) + return 1; /* stop if file fails */ + break; + } + default: break; + } + } + return 0; +} + + +static int handle_luainit (lua_State *L) { + const char *init = GETENV(LUA_INIT); + if (init == NULL) return 0; /* status OK */ + else if (init[0] == '@') + return dofile(L, init+1); + else + return dostring(L, init, "=" LUA_INIT); +} + + +struct Smain { + int argc; + char **argv; + int status; +}; + + +static int pmain (lua_State *L) { + struct Smain *s = (struct Smain *)lua_touserdata(L, 1); + char **argv = s->argv; + int script; + int has_i = 0, has_v = 0, has_e = 0; + globalL = L; + if (argv[0] && argv[0][0]) progname = argv[0]; + lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ + luaL_openlibs(L); /* open libraries */ + lua_gc(L, LUA_GCRESTART, 0); + s->status = handle_luainit(L); + if (s->status != 0) return 0; + script = collectargs(argv, &has_i, &has_v, &has_e); + if (script < 0) { /* invalid args? */ + print_usage(); + s->status = 1; + return 0; + } + if (has_v) print_version(); + s->status = runargs(L, argv, (script > 0) ? script : s->argc); + if (s->status != 0) return 0; + if (script) + s->status = handle_script(L, argv, script); + if (s->status != 0) return 0; + if (has_i) + dotty(L); + else if (script == 0 && !has_e && !has_v) { + if (lua_stdin_is_tty()) { + print_version(); + dotty(L); + } + else dofile(L, NULL); /* executes stdin as a file */ + } + return 0; +} + + +#ifdef GRUB_COMMAND +int grub_lua_main (int argc, char **argv) { +#else +int main (int argc, char **argv) { +#endif /* ! USE_GRUB_LIB */ + int status; + struct Smain s; + lua_State *L = lua_open(); /* create state */ + if (L == NULL) { + l_message(argv[0], "cannot create state: not enough memory"); + return EXIT_FAILURE; + } + s.argc = argc; + s.argv = argv; + status = lua_cpcall(L, &pmain, &s); + report(L, status); + lua_close(L); + return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; +} + === added file 'lua/lua.h' --- lua/lua.h 1970-01-01 00:00:00 +0000 +++ lua/lua.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,388 @@ +/* +** $Id: lua.h,v 1.218.1.4 2008/01/03 15:41:15 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.3" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif === added file 'lua/luac.c' --- lua/luac.c 1970-01-01 00:00:00 +0000 +++ lua/luac.c 2008-08-01 15:19:23 +0000 @@ -0,0 +1,200 @@ +/* +** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ +** Lua compiler (saves bytecodes to files; also list bytecodes) +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define luac_c +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" + +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstring.h" +#include "lundump.h" + +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static int stripping=0; /* strip debug information? */ +static char Output[]={ OUTPUT }; /* default output file name */ +static const char* output=Output; /* actual output file name */ +static const char* progname=PROGNAME; /* actual program name */ + +static void fatal(const char* message) +{ + fprintf(stderr,"%s: %s\n",progname,message); + exit(EXIT_FAILURE); +} + +static void cannot(const char* what) +{ + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); + exit(EXIT_FAILURE); +} + +static void usage(const char* message) +{ + if (*message=='-') + fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); + else + fprintf(stderr,"%s: %s\n",progname,message); + fprintf(stderr, + "usage: %s [options] [filenames].\n" + "Available options are:\n" + " - process stdin\n" + " -l list\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n", + progname,Output); + exit(EXIT_FAILURE); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +static int doargs(int argc, char* argv[]) +{ + int i; + int version=0; + if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; + for (i=1; itop+(i))->l.p) + +static const Proto* combine(lua_State* L, int n) +{ + if (n==1) + return toproto(L,-1); + else + { + int i,pc; + Proto* f=luaF_newproto(L); + setptvalue2s(L,L->top,f); incr_top(L); + f->source=luaS_newliteral(L,"=(" PROGNAME ")"); + f->maxstacksize=1; + pc=2*n+1; + f->code=luaM_newvector(L,pc,Instruction); + f->sizecode=pc; + f->p=luaM_newvector(L,n,Proto*); + f->sizep=n; + pc=0; + for (i=0; ip[i]=toproto(L,i-n-1); + f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); + f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); + } + f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); + return f; + } +} + +static int writer(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); +} + +struct Smain { + int argc; + char** argv; +}; + +static int pmain(lua_State* L) +{ + struct Smain* s = (struct Smain*)lua_touserdata(L, 1); + int argc=s->argc; + char** argv=s->argv; + const Proto* f; + int i; + if (!lua_checkstack(L,argc)) fatal("too many input files"); + for (i=0; i1); + if (dumping) + { + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); + if (D==NULL) cannot("open"); + lua_lock(L); + luaU_dump(L,f,writer,D,stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; +} + +int main(int argc, char* argv[]) +{ + lua_State* L; + struct Smain s; + int i=doargs(argc,argv); + argc-=i; argv+=i; + if (argc<=0) usage("no input files given"); + L=lua_open(); + if (L==NULL) fatal("not enough memory for state"); + s.argc=argc; + s.argv=argv; + if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); + lua_close(L); + return EXIT_SUCCESS; +} === added file 'lua/luacmd.c' --- lua/luacmd.c 1970-01-01 00:00:00 +0000 +++ lua/luacmd.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,69 @@ +/* luacmd.c - Lua interpreter command */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "luacmd.h" +#include "lua.h" +#include "lauxlib.h" + +static grub_err_t +grub_cmd_lua (struct grub_arg_list *state __attribute__ ((unused)), + int argc, + char **argv) +{ + /* Make a copy of the GRUB command's argv so we can put the command + name at index 0, like Lua's main function expects, as well as + terminating the argv array with a NULL pointer. */ + + char **main_argv = grub_malloc (sizeof (char *) * (argc + 2)); + if (! main_argv) + return grub_errno; + + main_argv[0] = "lua"; + grub_memcpy (&main_argv[1], argv, sizeof (char *) * (argc + 1)); + main_argv[argc + 1] = 0; + + int ret; + ret = grub_lua_main (argc + 1, main_argv); + grub_free (main_argv); + + return ret; +} + +GRUB_MOD_INIT(luacmd) +{ + (void)mod; /* To stop warning. */ + /* We use the NO_ARG_PARSE flag so command line options are passed + to the Lua interpreter for handling. */ + grub_register_command ("lua", grub_cmd_lua, + (GRUB_COMMAND_FLAG_BOTH + | GRUB_COMMAND_FLAG_NO_ARG_PARSE), + "lua", "Run the Lua interpreter", 0); +} + +GRUB_MOD_FINI(luacmd) +{ + grub_unregister_command ("lua"); +} + === added file 'lua/luacmd.h' --- lua/luacmd.h 1970-01-01 00:00:00 +0000 +++ lua/luacmd.h 2008-08-01 15:27:27 +0000 @@ -0,0 +1,25 @@ +/* luacmd.h - Lua command include file. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LUA_LUACMD_HEADER +#define GRUB_LUA_LUACMD_HEADER 1 + +int grub_lua_main (int argc, char **argv); + +#endif /* ! GRUB_LUA_LUACMD_HEADER */ === added file 'lua/luaconf.h' --- lua/luaconf.h 1970-01-01 00:00:00 +0000 +++ lua/luaconf.h 2008-08-01 15:27:27 +0000 @@ -0,0 +1,849 @@ +/* +** $Id: luaconf.h,v 1.82.1.6 2008/01/18 17:07:48 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#ifndef USE_GRUB_LIB +#include +#else /* USE_GRUB_LIB */ +# include "grublib.h" +# include +# include +# define assert(boolean) real_assert (boolean, __FILE__, __LINE__) +static inline void +real_assert (int boolean, const char *file, const int line) +{ + if (! boolean) + grub_printf ("Assertion failed at %s:%d\n", file, line); +} +#endif /* USE_GRUB_LIB */ + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ + +/* Changed to long for use with integral Lua numbers. */ +#define LUA_INTEGER long + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#define LUA_API extern + +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) + +#elif defined(USE_GRUB_LIB) +#include /* For grub_cmdline_get(), for user input. */ +#define lua_readline(L,buf,prompt) \ + ((void)L, buf[0]=0, grub_cmdline_get(prompt, buf, LUA_MAXINPUT, 0, 1)) +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } + +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif /* lua_c || luaall_c */ + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. +*/ +#define LUAI_MCS_AUX ((int)(INT_MAX / (4*sizeof(LUA_NUMBER)))) +#define LUAI_MAXCSTACK (LUAI_MCS_AUX > SHRT_MAX ? SHRT_MAX : LUAI_MCS_AUX) + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#ifdef USE_GRUB_LIB +#define LUAL_BUFFERSIZE 32768 +#else +#define LUAL_BUFFERSIZE BUFSIZ +#endif + +/* }================================================================== */ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +/* Define LUA_NUMBER_INTEGRAL to produce a system that uses no + floating point operations by changing the type of Lua numbers from + double to long. It implements division and modulus so that + + x == (x / y) * y + x % y. + + The exponentiation function returns zero for negative exponents. + Defining LUA_NUMBER_INTEGRAL also removes the difftime function, + and the math module should not be used. The string.format function + no longer handles the floating point directives %e, %E, %f, %g, and + %G. */ + +#define LUA_NUMBER_INTEGRAL +#if defined LUA_NUMBER_INTEGRAL +#define LUA_NUMBER long +#else +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double +#endif + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER LUA_NUMBER + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#if defined LUA_NUMBER_INTEGRAL +#define LUA_NUMBER_SCAN "%ld" +#define LUA_NUMBER_FMT "%ld" +#else +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#endif +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#if defined LUA_NUMBER_INTEGRAL +#define lua_str2number(s,p) strtol((s), (p), 10) +#else +#define lua_str2number(s,p) strtod((s), (p)) +#endif + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#if defined LUA_NUMBER_INTEGRAL +#define luai_numdiv(a,b) \ + (-1/2? \ + (a)/(b): \ + (((a)<0)==((b)<0)||(a)%(b)==0? \ + (a)/(b): \ + (a)/(b)-1)) +#define luai_nummod(a,b) \ + (-1/2? \ + (a)%(b): \ + (((a)<0)==((b)<0)||(a)%(b)==0? \ + (a)%(b): \ + (a)%(b)+(b))) +#define luai_lnumdiv(a,b) \ + ((b)==0? \ + (luaG_runerror(L,"divide by zero"),0): \ + luai_numdiv(a,b)) +#define luai_lnummod(a,b) \ + ((b)==0? \ + (luaG_runerror(L,"modulo by zero"),0): \ + luai_nummod(a,b)) +LUA_NUMBER luai_ipow(LUA_NUMBER, LUA_NUMBER); +#define luai_numpow(a,b) (luai_ipow(a,b)) +#else +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_lnumdiv(a,b) (luai_numdiv(a,b)) +#define luai_lnummod(a,b) (luai_nummod(a,b)) +#define luai_numpow(a,b) (pow(a,b)) +#endif +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(USE_GRUB_LIB) +#include +/* handling with long jumps, using the GRUB functions */ +#define LUAI_THROW(L,c) grub_longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (grub_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf grub_jmp_buf + +#elif defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#endif + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#if defined(LUA_USE_POPEN) + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) + +#elif defined(LUA_WIN) + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) + +#else + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +#endif + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + === added file 'lua/lualib.h' --- lua/lualib.h 1970-01-01 00:00:00 +0000 +++ lua/lualib.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,53 @@ +/* +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif === added file 'lua/lundump.c' --- lua/lundump.c 1970-01-01 00:00:00 +0000 +++ lua/lundump.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,227 @@ +/* +** $Id: lundump.c,v 2.7.1.2 2008/01/18 16:39:11 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lundump_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + +typedef struct { + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; +} LoadState; + +#ifdef LUAC_TRUST_BINARIES +#define IF(c,s) +#define error(S,s) +#else +#define IF(c,s) if (c) error(S,s) + +static void error(LoadState* S, const char* why) +{ + luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); + luaD_throw(S->L,LUA_ERRSYNTAX); +} +#endif + +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) +#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) + +static void LoadBlock(LoadState* S, void* b, size_t size) +{ + size_t r=luaZ_read(S->Z,b,size); + UNUSED(r); + IF (r!=0, "unexpected end"); +} + +static int LoadChar(LoadState* S) +{ + char x; + LoadVar(S,x); + return x; +} + +static int LoadInt(LoadState* S) +{ + int x; + LoadVar(S,x); + IF (x<0, "bad integer"); + return x; +} + +static lua_Number LoadNumber(LoadState* S) +{ + lua_Number x; + LoadVar(S,x); + return x; +} + +static TString* LoadString(LoadState* S) +{ + size_t size; + LoadVar(S,size); + if (size==0) + return NULL; + else + { + char* s=luaZ_openspace(S->L,S->b,size); + LoadBlock(S,s,size); + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode(LoadState* S, Proto* f) +{ + int n=LoadInt(S); + f->code=luaM_newvector(S->L,n,Instruction); + f->sizecode=n; + LoadVector(S,f->code,n,sizeof(Instruction)); +} + +static Proto* LoadFunction(LoadState* S, TString* p); + +static void LoadConstants(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->k=luaM_newvector(S->L,n,TValue); + f->sizek=n; + for (i=0; ik[i]); + for (i=0; ik[i]; + int t=LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o,LoadChar(S)); + break; + case LUA_TNUMBER: + setnvalue(o,LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L,o,LoadString(S)); + break; + default: + error(S,"bad constant"); + break; + } + } + n=LoadInt(S); + f->p=luaM_newvector(S->L,n,Proto*); + f->sizep=n; + for (i=0; ip[i]=NULL; + for (i=0; ip[i]=LoadFunction(S,f->source); +} + +static void LoadDebug(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->lineinfo=luaM_newvector(S->L,n,int); + f->sizelineinfo=n; + LoadVector(S,f->lineinfo,n,sizeof(int)); + n=LoadInt(S); + f->locvars=luaM_newvector(S->L,n,LocVar); + f->sizelocvars=n; + for (i=0; ilocvars[i].varname=NULL; + for (i=0; ilocvars[i].varname=LoadString(S); + f->locvars[i].startpc=LoadInt(S); + f->locvars[i].endpc=LoadInt(S); + } + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,TString*); + f->sizeupvalues=n; + for (i=0; iupvalues[i]=NULL; + for (i=0; iupvalues[i]=LoadString(S); +} + +static Proto* LoadFunction(LoadState* S, TString* p) +{ + Proto* f=luaF_newproto(S->L); + setptvalue2s(S->L,S->L->top,f); incr_top(S->L); + f->source=LoadString(S); if (f->source==NULL) f->source=p; + f->linedefined=LoadInt(S); + f->lastlinedefined=LoadInt(S); + f->nups=LoadByte(S); + f->numparams=LoadByte(S); + f->is_vararg=LoadByte(S); + f->maxstacksize=LoadByte(S); + LoadCode(S,f); + LoadConstants(S,f); + LoadDebug(S,f); + IF (!luaG_checkcode(f), "bad code"); + S->L->top--; + return f; +} + +static void LoadHeader(LoadState* S) +{ + char h[LUAC_HEADERSIZE]; + char s[LUAC_HEADERSIZE]; + luaU_header(h); + LoadBlock(S,s,LUAC_HEADERSIZE); + IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); +} + +/* +** load precompiled chunk +*/ +Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +{ + LoadState S; + if (*name=='@' || *name=='=') + S.name=name+1; + else if (*name==LUA_SIGNATURE[0]) + S.name="binary string"; + else + S.name=name; + S.L=L; + S.Z=Z; + S.b=buff; + LoadHeader(&S); + return LoadFunction(&S,luaS_newliteral(L,"=?")); +} + +/* +* make header +*/ +void luaU_header (char* h) +{ + int x=1; + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); + h+=sizeof(LUA_SIGNATURE)-1; + *h++=(char)LUAC_VERSION; + *h++=(char)LUAC_FORMAT; + *h++=(char)*(char*)&x; /* endianness */ + *h++=(char)sizeof(int); + *h++=(char)sizeof(size_t); + *h++=(char)sizeof(Instruction); + *h++=(char)sizeof(lua_Number); + *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ +} === added file 'lua/lundump.h' --- lua/lundump.h 1970-01-01 00:00:00 +0000 +++ lua/lundump.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,36 @@ +/* +** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "lobject.h" +#include "lzio.h" + +/* load one chunk; from lundump.c */ +LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); + +/* make header; from lundump.c */ +LUAI_FUNC void luaU_header (char* h); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); + +#ifdef luac_c +/* print one chunk; from print.c */ +LUAI_FUNC void luaU_print (const Proto* f, int full); +#endif + +/* for header of binary files -- this is Lua 5.1 */ +#define LUAC_VERSION 0x51 + +/* for header of binary files -- this is the official format */ +#define LUAC_FORMAT 0 + +/* size of header of binary files */ +#define LUAC_HEADERSIZE 12 + +#endif === added file 'lua/lvm.c' --- lua/lvm.c 1970-01-01 00:00:00 +0000 +++ lua/lvm.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,784 @@ +/* +** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#include +#include +#endif /* ! USE_GRUB_LIB */ + +#define lvm_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + +#if defined LUA_NUMBER_INTEGRAL +LUA_NUMBER luai_ipow(LUA_NUMBER a, LUA_NUMBER b) { + if (b < 0) + return 0; + else if (b == 0) + return 1; + else { + LUA_NUMBER c = 1; + for (;;) { + if (b & 1) + c *= a; + b = b >> 1; + if (b == 0) + return c; + a *= a; + } + } +} +#endif + +/* limit for table tag-method chains (to avoid loops) */ +#define MAXTAGLOOP 100 + + +const TValue *luaV_tonumber (const TValue *obj, TValue *n) { + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { + setnvalue(n, num); + return n; + } + else + return NULL; +} + + +int luaV_tostring (lua_State *L, StkId obj) { + if (!ttisnumber(obj)) + return 0; + else { + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + lua_number2str(s, n); + setsvalue2s(L, obj, luaS_new(L, s)); + return 1; + } +} + + +static void traceexec (lua_State *L, const Instruction *pc) { + lu_byte mask = L->hookmask; + const Instruction *oldpc = L->savedpc; + L->savedpc = pc; + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); + } + if (mask & LUA_MASKLINE) { + Proto *p = ci_func(L->ci)->l.p; + int npc = pcRel(pc, p); + int newline = getline(p, npc); + /* call linehook when enter a new function, when jump back (loop), + or when enter a new line */ + if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) + luaD_callhook(L, LUA_HOOKLINE, newline); + } +} + + +static void callTMres (lua_State *L, StkId res, const TValue *f, + const TValue *p1, const TValue *p2) { + ptrdiff_t result = savestack(L, res); + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + luaD_checkstack(L, 3); + L->top += 3; + luaD_call(L, L->top - 3, 1); + res = restorestack(L, result); + L->top--; + setobjs2s(L, res, L->top); +} + + + +static void callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3) { + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + setobj2s(L, L->top+3, p3); /* 3th argument */ + luaD_checkstack(L, 4); + L->top += 4; + luaD_call(L, L->top - 4, 0); +} + + +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + const TValue *res = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTMres(L, val, tm, t, key); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in gettable"); +} + + +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ + if (!ttisnil(oldval) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ + setobj2t(L, oldval, val); + luaC_barriert(L, h, val); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in settable"); +} + + +static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + callTMres(L, res, tm, p1, p2); + return 1; +} + + +static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, + TMS event) { + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; +} + + +static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, + TMS event) { + const TValue *tm1 = luaT_gettmbyobj(L, p1, event); + const TValue *tm2; + if (ttisnil(tm1)) return -1; /* no metamethod? */ + tm2 = luaT_gettmbyobj(L, p2, event); + if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ + return -1; + callTMres(L, L->top, tm1, p1, p2); + return !l_isfalse(L->top); +} + + +static int l_strcmp (const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numlt(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) + return res; + return luaG_ordererror(L, l, r); +} + + +static int lessequal (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numle(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ + return !res; + return luaG_ordererror(L, l, r); +} + + +int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + lua_assert(ttype(t1) == ttype(t2)); + switch (ttype(t1)) { + case LUA_TNIL: return 1; + case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, + TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTMres(L, L->top, tm, t1, t2); /* call TM */ + return !l_isfalse(L->top); +} + + +void luaV_concat (lua_State *L, int total, int last) { + do { + StkId top = L->base + last + 1; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) + luaG_concaterror(L, top-2, top-1); + } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ + (void)tostring(L, top - 2); /* result is first op (as string) */ + else { + /* at least two string values; get as many as possible */ + size_t tl = tsvalue(top-1)->len; + char *buffer; + int i; + /* collect total length */ + for (n = 1; n < total && tostring(L, top-n-1); n++) { + size_t l = tsvalue(top-n-1)->len; + if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); + tl += l; + } + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + for (i=n; i>0; i--) { /* concat all strings */ + size_t l = tsvalue(top-i)->len; + memcpy(buffer+tl, svalue(top-i), l); + tl += l; + } + setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); + } + total -= n-1; /* got `n' strings to create 1 new */ + last -= n-1; + } while (total > 1); /* repeat until only 1 result left */ +} + + +static void Arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) { + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) { + lua_Number nb = nvalue(b), nc = nvalue(c); + switch (op) { + case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; + case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; + case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; + case TM_DIV: setnvalue(ra, luai_lnumdiv(nb, nc)); break; + case TM_MOD: setnvalue(ra, luai_lnummod(nb, nc)); break; + case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; + case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; + default: lua_assert(0); break; + } + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); +} + + + +/* +** some macros for common tasks in `luaV_execute' +*/ + +#define runtime_check(L, c) { if (!(c)) break; } + +#define RA(i) (base+GETARG_A(i)) +/* to be used after possible stack reallocation */ +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) +#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) + + +#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} + + +#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } + + +#define arith_op(op,tm) { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(nb, nc)); \ + } \ + else \ + Protect(Arith(L, ra, rb, rc, tm)); \ + } + + + +void luaV_execute (lua_State *L, int nexeccalls) { + LClosure *cl; + StkId base; + TValue *k; + const Instruction *pc; + reentry: /* entry point */ + lua_assert(isLua(L->ci)); + pc = L->savedpc; + cl = &clvalue(L->ci->func)->l; + base = L->base; + k = cl->p->k; + /* main loop of interpreter */ + for (;;) { + const Instruction i = *pc++; + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { + traceexec(L, pc); + if (L->status == LUA_YIELD) { /* did hook yield? */ + L->savedpc = pc - 1; + return; + } + base = L->base; + } + /* warning!! several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == L->base && L->base == L->ci->base); + lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); + lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); + switch (GET_OPCODE(i)) { + case OP_MOVE: { + setobjs2s(L, ra, RB(i)); + continue; + } + case OP_LOADK: { + setobj2s(L, ra, KBx(i)); + continue; + } + case OP_LOADBOOL: { + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ + continue; + } + case OP_LOADNIL: { + TValue *rb = RB(i); + do { + setnilvalue(rb--); + } while (rb >= ra); + continue; + } + case OP_GETUPVAL: { + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v); + continue; + } + case OP_GETGLOBAL: { + TValue g; + TValue *rb = KBx(i); + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(rb)); + Protect(luaV_gettable(L, &g, rb, ra)); + continue; + } + case OP_GETTABLE: { + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + continue; + } + case OP_SETGLOBAL: { + TValue g; + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(KBx(i))); + Protect(luaV_settable(L, &g, KBx(i), ra)); + continue; + } + case OP_SETUPVAL: { + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + continue; + } + case OP_SETTABLE: { + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + continue; + } + case OP_NEWTABLE: { + int b = GETARG_B(i); + int c = GETARG_C(i); + sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); + Protect(luaC_checkGC(L)); + continue; + } + case OP_SELF: { + StkId rb = RB(i); + setobjs2s(L, ra+1, rb); + Protect(luaV_gettable(L, rb, RKC(i), ra)); + continue; + } + case OP_ADD: { + arith_op(luai_numadd, TM_ADD); + continue; + } + case OP_SUB: { + arith_op(luai_numsub, TM_SUB); + continue; + } + case OP_MUL: { + arith_op(luai_nummul, TM_MUL); + continue; + } + case OP_DIV: { + arith_op(luai_lnumdiv, TM_DIV); + continue; + } + case OP_MOD: { + arith_op(luai_lnummod, TM_MOD); + continue; + } + case OP_POW: { + arith_op(luai_numpow, TM_POW); + continue; + } + case OP_UNM: { + TValue *rb = RB(i); + if (ttisnumber(rb)) { + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(nb)); + } + else { + Protect(Arith(L, ra, rb, rb, TM_UNM)); + } + continue; + } + case OP_NOT: { + int res = l_isfalse(RB(i)); /* next assignment may change this value */ + setbvalue(ra, res); + continue; + } + case OP_LEN: { + const TValue *rb = RB(i); + switch (ttype(rb)) { + case LUA_TTABLE: { + setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); + break; + } + case LUA_TSTRING: { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + break; + } + default: { /* try metamethod */ + Protect( + if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) + luaG_typeerror(L, rb, "get length of"); + ) + } + } + continue; + } + case OP_CONCAT: { + int b = GETARG_B(i); + int c = GETARG_C(i); + Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); + setobjs2s(L, RA(i), base+b); + continue; + } + case OP_JMP: { + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_EQ: { + TValue *rb = RKB(i); + TValue *rc = RKC(i); + Protect( + if (equalobj(L, rb, rc) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LT: { + Protect( + if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LE: { + Protect( + if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_TEST: { + if (l_isfalse(ra) != GETARG_C(i)) + dojump(L, pc, GETARG_sBx(*pc)); + pc++; + continue; + } + case OP_TESTSET: { + TValue *rb = RB(i); + if (l_isfalse(rb) != GETARG_C(i)) { + setobjs2s(L, ra, rb); + dojump(L, pc, GETARG_sBx(*pc)); + } + pc++; + continue; + } + case OP_CALL: { + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + switch (luaD_precall(L, ra, nresults)) { + case PCRLUA: { + nexeccalls++; + goto reentry; /* restart luaV_execute over new Lua function */ + } + case PCRC: { + /* it was a C function (`precall' called it); adjust results */ + if (nresults >= 0) L->top = L->ci->top; + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_TAILCALL: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); + switch (luaD_precall(L, ra, LUA_MULTRET)) { + case PCRLUA: { + /* tail call: put new frame in place of previous one */ + CallInfo *ci = L->ci - 1; /* previous frame */ + int aux; + StkId func = ci->func; + StkId pfunc = (ci+1)->func; /* previous function index */ + if (L->openupval) luaF_close(L, ci->base); + L->base = ci->base = ci->func + ((ci+1)->base - pfunc); + for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ + setobjs2s(L, func+aux, pfunc+aux); + ci->top = L->top = func+aux; /* correct top */ + lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); + ci->savedpc = L->savedpc; + ci->tailcalls++; /* one more call lost */ + L->ci--; /* remove new frame */ + goto reentry; + } + case PCRC: { /* it was a C function (`precall' called it) */ + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_RETURN: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b-1; + if (L->openupval) luaF_close(L, base); + L->savedpc = pc; + b = luaD_poscall(L, ra); + if (--nexeccalls == 0) /* was previous function running `here'? */ + return; /* no: return */ + else { /* yes: continue its execution */ + if (b) L->top = L->ci->top; + lua_assert(isLua(L->ci)); + lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); + goto reentry; + } + } + case OP_FORLOOP: { + lua_Number step = nvalue(ra+2); + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra+1); + if (luai_numlt(0, step) ? luai_numle(idx, limit) + : luai_numle(limit, idx)) { + dojump(L, pc, GETARG_sBx(i)); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra+3, idx); /* ...and external index */ + } + continue; + } + case OP_FORPREP: { + const TValue *init = ra; + const TValue *plimit = ra+1; + const TValue *pstep = ra+2; + L->savedpc = pc; /* next steps may throw errors */ + if (!tonumber(init, ra)) + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + else if (!tonumber(plimit, ra+1)) + luaG_runerror(L, LUA_QL("for") " limit must be a number"); + else if (!tonumber(pstep, ra+2)) + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_TFORLOOP: { + StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb+2, ra+2); + setobjs2s(L, cb+1, ra+1); + setobjs2s(L, cb, ra); + L->top = cb+3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i))); + L->top = L->ci->top; + cb = RA(i) + 3; /* previous call may change the stack */ + if (!ttisnil(cb)) { /* continue loop? */ + setobjs2s(L, cb-1, cb); /* save control variable */ + dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ + } + pc++; + continue; + } + case OP_SETLIST: { + int n = GETARG_B(i); + int c = GETARG_C(i); + int last; + Table *h; + if (n == 0) { + n = cast_int(L->top - ra) - 1; + L->top = L->ci->top; + } + if (c == 0) c = cast_int(*pc++); + runtime_check(L, ttistable(ra)); + h = hvalue(ra); + last = ((c-1)*LFIELDS_PER_FLUSH) + n; + if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-alloc it at once */ + for (; n > 0; n--) { + TValue *val = ra+n; + setobj2t(L, luaH_setnum(L, h, last--), val); + luaC_barriert(L, h, val); + } + continue; + } + case OP_CLOSE: { + luaF_close(L, ra); + continue; + } + case OP_CLOSURE: { + Proto *p; + Closure *ncl; + int nup, j; + p = cl->p->p[GETARG_Bx(i)]; + nup = p->nups; + ncl = luaF_newLclosure(L, nup, cl->env); + ncl->l.p = p; + for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; + else { + lua_assert(GET_OPCODE(*pc) == OP_MOVE); + ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); + } + } + setclvalue(L, ra, ncl); + Protect(luaC_checkGC(L)); + continue; + } + case OP_VARARG: { + int b = GETARG_B(i) - 1; + int j; + CallInfo *ci = L->ci; + int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; + if (b == LUA_MULTRET) { + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + b = n; + L->top = ra + n; + } + for (j = 0; j < b; j++) { + if (j < n) { + setobjs2s(L, ra + j, ci->base - n + j); + } + else { + setnilvalue(ra + j); + } + } + continue; + } + } + } +} + === added file 'lua/lvm.h' --- lua/lvm.h 1970-01-01 00:00:00 +0000 +++ lua/lvm.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,36 @@ +/* +** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) + +#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ + (((o) = luaV_tonumber(o,n)) != NULL)) + +#define equalobj(L,o1,o2) \ + (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) + + +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); +LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); +LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); + +#endif === added file 'lua/lzio.c' --- lua/lzio.c 1970-01-01 00:00:00 +0000 +++ lua/lzio.c 2008-08-01 15:27:27 +0000 @@ -0,0 +1,84 @@ +/* +** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** a generic input stream interface +** See Copyright Notice in lua.h +*/ + + +#ifndef USE_GRUB_LIB +#include +#endif /* ! USE_GRUB_LIB */ + +#define lzio_c +#define LUA_CORE + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) return EOZ; + z->n = size - 1; + z->p = buff; + return char2int(*(z->p++)); +} + + +int luaZ_lookahead (ZIO *z) { + if (z->n == 0) { + if (luaZ_fill(z) == EOZ) + return EOZ; + else { + z->n++; /* luaZ_fill removed first byte; put back it */ + z->p--; + } + } + return char2int(*z->p); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (luaZ_lookahead(z) == EOZ) + return n; /* return number of missing bytes */ + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; +} + + === added file 'lua/lzio.h' --- lua/lzio.h 1970-01-01 00:00:00 +0000 +++ lua/lzio.h 2008-08-01 15:19:23 +0000 @@ -0,0 +1,67 @@ +/* +** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define char2int(c) cast(int, cast(unsigned char, (c))) + +#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ +LUAI_FUNC int luaZ_lookahead (ZIO *z); + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; + void* data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif === added file 'lua/print.c' --- lua/print.c 1970-01-01 00:00:00 +0000 +++ lua/print.c 2008-08-01 15:19:23 +0000 @@ -0,0 +1,227 @@ +/* +** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lundump.h" + +#define PrintFunction luaU_print + +#define Sizeof(x) ((int)sizeof(x)) +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + putchar('"'); + for (i=0; ik[i]; + switch (ttype(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); + break; + case iABx: + if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); + break; + case iAsBx: + if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); + break; + case OP_GETGLOBAL: + case OP_SETGLOBAL: + printf("\t; %s",svalue(&f->k[bx])); + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); + else printf("\t; %d",c); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) (x==1)?"":"s" +#define S(x) x,SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=getstr(f->source); + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintConstants(const Proto* f) +{ + int i,n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } +} + +static void PrintUpvalues(const Proto* f) +{ + int i,n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + if (f->upvalues==NULL) return; + for (i=0; iupvalues[i])); + } +} + +void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) + { + PrintConstants(f); + PrintLocals(f); + PrintUpvalues(f); + } + for (i=0; ip[i],full); +} # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWbFxDlgBt+H/gH////////// //////////9iX/4e+d697071tXn3SuO6j72PR7e4+vvbmq31X19FFIFACOn3ddJSKWjJQh29UOig AejVACgKoAANBUr7z6PCrrPJz75vpb13HfT0aTn3h30D4oVNH0d0fSlCjpAB76N82ergbBvvfa97 erE2wXvdcepdhzrG27ppsCmjFSIjWxxvY1XeDbPuzuA4g5mO8cZ3vcVsGs000ZWtVA1WmtUqvbdU dtS2rDMtfK7aTrG9Xq+O+DvuFHNbJlyj6QE6aO+mOYjMl93M68zp5rPeW9eO7Trb675Gqe+fb3tr 3c5nS973o3vc8bve8Zz5Rz1D2eD1Q8uHvvOq773vHsVVst9rR7jCoVdZJm29XI3bV3bOd1J2woFy 2rdunbAwTNHD66vKte7e9uE67tmzseuwFtJG2M1mvdxPXnkb1zyCpsV73eoXOW3HvuO98OQKsfff ZpiBA4ml8AAdz29UfedwfeGuh9JA3YFCnjuUCtmbW095rvdbnaJlh9LN6Gmg9Oj3mIKAAU9CQNAH 00AHSgNAAAAAUAAaUAAABQAFEgFDT76qqhShKgK6aKovPK8gXd92vfbfWdjOgyVO2IiPoaSey+GB 32Z0bWiSI6yU9zuuluHV2lt9s6trZBGeD4zRu3cGXVKGrRo90kqgV7vja++fN7uPO8W1a93ebSer W99RCrc+fdXWxmbbbHw26C7HXO63A7YLZtos3ve891yjrIMaZo0KGqYg0Wxpq0wqlGsUbNs0VKkZ jCrMySpFayK9drB13vO13A027vbeje7OHetmt11phab3cOTy66KY3XVK22sfYND5nvd9RoMhJSr0 A+wRuuXPrnegmworfZ3bWez7ffHikeduV73Tyb1PpoLTa2pkgGmbPrTtfTpsGgAQBF1LAoopRVLD 57c9qhWigfTFxGMzWtGBm33N1K94Pd6UAFFKWEdQt1u8aaN4+x9clH0y7d93mnkAc73vJN7upJ6z tk0tsa19bz6TfOvHRs22zk6XeFc0oUnW2bbfNo3M6igbuceatnjDtmd3PmuLnqs8WOq5ssnrupuj 3zqHHvOJ276+900ZPvLM7uZXfZ13w4cHKmSKTrK6YBFcL1rZNbVtd3c2989W23jvnZYiC7aUjXub 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 X//i7kinChIWLiHLAA==