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