1 /*- 2 * Copyright (c) 2011 Wojciech A. Koszek <wkoszek@FreeBSD.org> 3 * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <stand.h> 32 #include "bootstrap.h" 33 34 #define lua_c 35 36 #include "lstd.h" 37 38 #include <lua.h> 39 #include <ldebug.h> 40 #include <lauxlib.h> 41 #include <lualib.h> 42 #include <lutils.h> 43 44 struct interp_lua_softc { 45 lua_State *luap; 46 }; 47 48 static struct interp_lua_softc lua_softc; 49 50 #ifdef LUA_DEBUG 51 #define LDBG(...) do { \ 52 printf("%s(%d): ", __func__, __LINE__); \ 53 printf(__VA_ARGS__); \ 54 printf("\n"); \ 55 } while (0) 56 #else 57 #define LDBG(...) 58 #endif 59 60 61 static void * 62 interp_lua_realloc(void *ud __unused, void *ptr, size_t osize __unused, size_t nsize) 63 { 64 65 if (nsize == 0) { 66 free(ptr); 67 return NULL; 68 } 69 return realloc(ptr, nsize); 70 } 71 72 /* 73 * The libraries commented out below either lack the proper 74 * support from libsa, or they are unlikely to be useful 75 * in the bootloader, so have been commented out. 76 */ 77 static const luaL_Reg loadedlibs[] = { 78 {"_G", luaopen_base}, 79 {LUA_LOADLIBNAME, luaopen_package}, 80 // {LUA_COLIBNAME, luaopen_coroutine}, 81 // {LUA_TABLIBNAME, luaopen_table}, 82 {LUA_STRLIBNAME, luaopen_string}, 83 // {LUA_IOLIBNAME, luaopen_io}, 84 // {LUA_OSLIBNAME, luaopen_os}, 85 // {LUA_MATHLIBNAME, luaopen_math}, 86 // {LUA_UTF8LIBNAME, luaopen_utf8}, 87 // {LUA_DBLIBNAME, luaopen_debug}, 88 {NULL, NULL} 89 }; 90 91 void 92 interp_init(void) 93 { 94 lua_State *luap; 95 struct interp_lua_softc *softc = &lua_softc; 96 const char *filename; 97 const luaL_Reg *lib; 98 99 setenv("script.lang", "lua", 1); 100 LDBG("creating context"); 101 102 luap = lua_newstate(interp_lua_realloc, NULL); 103 if (luap == NULL) { 104 printf("problem initializing the Lua interpreter\n"); 105 abort(); 106 } 107 softc->luap = luap; 108 register_utils(luap); 109 110 /* "require" functions from 'loadedlibs' and set results to global table */ 111 for (lib = loadedlibs; lib->func; lib++) { 112 luaL_requiref(luap, lib->name, lib->func, 1); 113 lua_pop(luap, 1); /* remove lib */ 114 } 115 116 filename = "/boot/lua/loader.lua"; 117 if (interp_include(filename) != 0) { 118 const char *errstr = lua_tostring(luap, -1); 119 errstr = errstr == NULL ? "unknown" : errstr; 120 printf("Startup errorr in %s:\nLUA ERROR: %s.\n", filename, errstr); 121 lua_pop(luap, 1); 122 } 123 } 124 125 int 126 interp_run(const char *line) 127 { 128 int argc; 129 char **argv; 130 lua_State *luap; 131 struct interp_lua_softc *softc = &lua_softc; 132 int status; 133 134 luap = softc->luap; 135 LDBG("executing line..."); 136 if ((status = luaL_dostring(luap, line)) != 0) { 137 /* 138 * If we could not parse the line as Lua syntax, 139 * try parsing it as a loader command. 140 */ 141 lua_pop(luap, 1); 142 if (parse(&argc, &argv, line) == 0) { 143 status = interp_builtin_cmd(argc, argv); 144 if (status != CMD_OK) 145 printf("Command failed\n"); 146 free(argv); 147 } else { 148 printf("Failed to parse \'%s\'\n", line); 149 status = -1; 150 } 151 } 152 153 return (status == 0 ? CMD_OK : CMD_ERROR); 154 } 155 156 int 157 interp_include(const char *filename) 158 { 159 struct interp_lua_softc *softc = &lua_softc; 160 161 LDBG("loading file %s", filename); 162 163 return (luaL_dofile(softc->luap, filename)); 164 } 165