168 lines
5.4 KiB
C
168 lines
5.4 KiB
C
/*
|
|
** $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
|
|
#define LUAC_CROSS_FILE
|
|
|
|
#include "lua.h"
|
|
|
|
#include "lualib.h"
|
|
#include "lauxlib.h"
|
|
#include "luaconf.h"
|
|
#include "module.h"
|
|
#include "lstate.h"
|
|
#include "lrotable.h"
|
|
#include <assert.h>
|
|
#include <stdalign.h>
|
|
|
|
LROT_EXTERN(strlib);
|
|
LROT_EXTERN(tab_funcs);
|
|
LROT_EXTERN(dblib);
|
|
LROT_EXTERN(co_funcs);
|
|
LROT_EXTERN(math);
|
|
#if defined(LUA_CROSS_COMPILER)
|
|
LROT_EXTERN(oslib);
|
|
//LROT_EXTERN(iolib);
|
|
#endif
|
|
/*
|
|
* The NodeMCU Lua initalisation has been adapted to use linker-based module
|
|
* registration. This uses a PSECT naming convention to allow the ROTable and
|
|
* initialisation function entries to be collected by the linker into two
|
|
* consoliated ROTables. This significantly simplifies adding new modules and
|
|
* configuring builds with a small subset of the total modules.
|
|
*
|
|
* This linker-based approach is not practical for cross compiler builds which
|
|
* must link on a range of platforms, and where we don't have control of PSECT
|
|
* placement. However unlike the target builds, the luac.cross builds only
|
|
* used a small and fixed list of libraries and so in this case the table can
|
|
* be defined in this source file, so in this case all library ROTables are
|
|
* defined here, avoiding the need for linker magic is avoided on host builds.
|
|
*
|
|
* Note that a separate ROTable is defined in lbaselib.c for the base functions
|
|
* and there is a metatable index cascade from _G to this base function table to
|
|
* the master rotables table. In the target build, the linker marshals the
|
|
* table, hence the LROT_BREAK() macros which don't 0 terminate the lists.
|
|
*/
|
|
|
|
#ifdef _MSC_VER
|
|
//MSVC requires us to declare these sections before we refer to them
|
|
#pragma section(__ROSECNAME(A), read)
|
|
#pragma section(__ROSECNAME(zzzzzzzz), read)
|
|
#pragma section(__ROSECNAME(libs), read)
|
|
#pragma section(__ROSECNAME(rotable), read)
|
|
//These help us to find the beginning and ending of the RO data. NOTE: linker
|
|
//magic is used; the section names are lexically sorted, so 'a' and 'z' are
|
|
//important to keep the other sections lexically between these two dummy
|
|
//variables. Check your mapfile output if you need to fiddle with this stuff.
|
|
const LOCK_IN_SECTION(A) char _ro_start[1] = {0};
|
|
const LOCK_IN_SECTION(zzzzzzzz) char _ro_end[1] = {0};
|
|
#endif
|
|
|
|
#if defined(LUA_CROSS_COMPILER)
|
|
|
|
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(rotable) lua_rotables)
|
|
LROT_TABENTRY( string, strlib )
|
|
LROT_TABENTRY( table, tab_funcs )
|
|
LROT_TABENTRY( coroutine, co_funcs )
|
|
LROT_TABENTRY( debug, dblib)
|
|
LROT_TABENTRY( math, math )
|
|
LROT_TABENTRY( ROM, lua_rotables )
|
|
LROT_TABENTRY( os, oslib )
|
|
//LROT_TABENTRY( io, iolib )
|
|
LROT_END(lua_rotables, NULL, 0)
|
|
|
|
#else
|
|
|
|
// Due to limitations in the IDF linker fragment generation, we have to
|
|
// play with link-time symbol generation/aliasing to set up the rotables
|
|
// properly. As part of that, we need to use a different name for the
|
|
// table here.
|
|
|
|
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(rotable) lua_rotables_part)
|
|
#ifdef CONFIG_LUA_BUILTIN_STRING
|
|
LROT_TABENTRY( string, strlib )
|
|
#endif
|
|
#ifdef CONFIG_LUA_BUILTIN_TABLE
|
|
LROT_TABENTRY( table, tab_funcs )
|
|
#endif
|
|
#ifdef CONFIG_LUA_BUILTIN_COROUTINE
|
|
LROT_TABENTRY( coroutine, co_funcs )
|
|
#endif
|
|
#ifdef CONFIG_LUA_BUILTIN_DEBUG
|
|
LROT_TABENTRY( debug, dblib)
|
|
#endif
|
|
#ifdef CONFIG_LUA_BUILTIN_MATH
|
|
LROT_TABENTRY( math, math )
|
|
#endif
|
|
LROT_TABENTRY( ROM, lua_rotables_part )
|
|
LROT_BREAK(lua_rotables_part)
|
|
|
|
#endif
|
|
|
|
|
|
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(libs) lua_libs)
|
|
LROT_FUNCENTRY( _, luaopen_base )
|
|
LROT_FUNCENTRY( package, luaopen_package )
|
|
#ifdef CONFIG_LUA_BUILTIN_STRING
|
|
LROT_FUNCENTRY( string, luaopen_string )
|
|
#endif
|
|
#ifdef CONFIG_LUA_BUILTIN_TABLE
|
|
LROT_FUNCENTRY( table, luaopen_table )
|
|
#endif
|
|
#ifdef CONFIG_LUA_BUILTIN_DEBUG
|
|
LROT_FUNCENTRY( debug, luaopen_debug )
|
|
#endif
|
|
#ifndef LUA_CROSS_COMPILER
|
|
LROT_BREAK(lua_libs)
|
|
#else
|
|
LROT_FUNCENTRY( io, luaopen_io )
|
|
LROT_END( lua_libs, NULL, 0)
|
|
#endif
|
|
|
|
#ifndef LUA_CROSS_COMPILER
|
|
extern void luaL_dbgbreak(void);
|
|
#endif
|
|
|
|
/* Historically the linker script took care of zero terminating both the
|
|
* lua_libs and lua_rotable arrays, but the IDF currently does not
|
|
* support injecting LONG(0) entries. To compensate, we have explicit
|
|
* end markers here which the linker fragment then place appropriately
|
|
* to terminate aforementioned arrays.
|
|
*/
|
|
const luaR_entry LOCK_IN_SECTION(libs_end_marker) libs_end_marker= { 0, };
|
|
const luaR_entry LOCK_IN_SECTION(rotable_end_marker) rotable_end_marker = { 0, };
|
|
|
|
void luaL_openlibs (lua_State *L) {
|
|
lua_pushrotable(L, LROT_TABLEREF(lua_libs));
|
|
lua_pushnil(L); /* first key */
|
|
/* loop round and open libraries */
|
|
#ifndef LUA_CROSS_COMPILER
|
|
// luaL_dbgbreak(); // This is a test point for debugging library start ups
|
|
#endif
|
|
while (lua_next(L, -2) != 0) {
|
|
if (lua_islightfunction(L,-1) &&
|
|
fvalue(L->top-1)) { // only process function entries
|
|
lua_pushvalue(L, -2);
|
|
lua_call(L, 1, 0); // call luaopen_XXX(libname)
|
|
} else {
|
|
lua_pop(L, 1);
|
|
}
|
|
}
|
|
lua_pop(L, 1); //cleanup stack
|
|
}
|
|
|
|
#ifndef LUA_CROSS_COMPILER
|
|
# ifdef LUA_NUMBER_INTEGRAL
|
|
# define COMPARE <=
|
|
# else
|
|
# define COMPARE ==
|
|
# endif
|
|
_Static_assert(_Alignof(luaR_entry) COMPARE 8, "Unexpected alignment of module registration - update the linker script snippets to match!");
|
|
_Static_assert(sizeof(luaR_entry) COMPARE 24, "Unexpect size of array member - update the linker script snippets to match!");
|
|
#endif
|