100 lines
3.4 KiB
C
100 lines
3.4 KiB
C
/* Read-only tables for Lua */
|
|
|
|
#ifndef lrotable_h
|
|
#define lrotable_h
|
|
|
|
#include "lua.h"
|
|
#include "luaconf.h"
|
|
#include "lobject.h"
|
|
#include "llimits.h"
|
|
|
|
/* Macros one can use to define rotable entries */
|
|
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
|
|
#define LRO_LUDATA(v) {{.p = v}, LUA_TLIGHTUSERDATA}
|
|
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
|
|
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
|
|
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
|
|
|
|
#ifdef LUA_CROSS_COMPILER
|
|
#define LRO_STRKEY(k) k
|
|
#else
|
|
#define LRO_STRKEY(k) ((__attribute__((aligned(4))) char *) k)
|
|
#endif
|
|
|
|
#define LROT_TABLE(t) static const LUA_REG_TYPE t ## _map[];
|
|
#define LROT_PUBLIC_TABLE(t) const LUA_REG_TYPE t ## _map[];
|
|
#define LROT_TABLEREF(t) ((void *) t ## _map)
|
|
#define LROT_BEGIN(t) static const LUA_REG_TYPE t ## _map [] = {
|
|
#define LROT_PUBLIC_BEGIN(t) const LUA_REG_TYPE t ## _map[] = {
|
|
#define LROT_EXTERN(t) extern const LUA_REG_TYPE t ## _map[]
|
|
#define LROT_TABENTRY(n,t) {LRO_STRKEY(#n), LRO_ROVAL(t ## _map)},
|
|
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
|
|
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
|
|
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA((void *) x)},
|
|
#define LROT_END(t,mt, f) {NULL, LRO_NILVAL} };
|
|
#define LROT_BREAK(t) };
|
|
|
|
#define LUA_REG_TYPE luaR_entry
|
|
#define LREGISTER(L, name, table) return 0
|
|
|
|
/* Maximum length of a rotable name and of a string key*/
|
|
#define LUA_MAX_ROTABLE_NAME 32
|
|
|
|
/* Type of a numeric key in a rotable */
|
|
typedef int luaR_numkey;
|
|
|
|
/* An entry in the read only table */
|
|
typedef struct luaR_entry {
|
|
const char *key;
|
|
const TValue value;
|
|
} luaR_entry;
|
|
|
|
/*
|
|
* The current ROTable implmentation is a vector of luaR_entry terminated by a
|
|
* nil record. The convention is to use ROtable * to refer to the entire vector
|
|
* as a logical ROTable.
|
|
*/
|
|
typedef const struct luaR_entry ROTable;
|
|
|
|
const TValue* luaR_findentry(ROTable *tab, TString *key, unsigned *ppos);
|
|
const TValue* luaR_findentryN(ROTable *tab, luaR_numkey numkey, unsigned *ppos);
|
|
void luaR_next(lua_State *L, ROTable *tab, TValue *key, TValue *val);
|
|
void* luaR_getmeta(ROTable *tab);
|
|
int luaR_isrotable(void *p);
|
|
|
|
/*
|
|
* Set inRO check depending on platform. Note that this implementation needs
|
|
* to work on both the host (luac.cross) and ESP targets. The luac.cross
|
|
* VM is used for the -e option, and is primarily used to be able to debug
|
|
* VM changes on the more developer-friendly hot gdb environment.
|
|
*/
|
|
#if defined(LUA_CROSS_COMPILER)
|
|
|
|
#if defined(_MSC_VER)
|
|
//msvc build uses these dummy vars to locate the beginning and ending addresses of the RO data
|
|
extern const char _ro_start[], _ro_end[];
|
|
#define IN_RODATA_AREA(p) (((const char*)(p)) >= _ro_start && ((const char *)(p)) <= _ro_end)
|
|
#else /* one of the POSIX variants */
|
|
#if defined(__CYGWIN__)
|
|
#define _RODATA_END __end__
|
|
#elif defined(__MINGW32__)
|
|
#define _RODATA_END end
|
|
#else
|
|
#define _RODATA_END _edata
|
|
#endif
|
|
extern const char _RODATA_END[];
|
|
#define IN_RODATA_AREA(p) (((const char *)(p)) < _RODATA_END)
|
|
#endif /* defined(_MSC_VER) */
|
|
|
|
#else /* xtensa tool chain for ESP32 target */
|
|
|
|
#include "compiler.h"
|
|
#define IN_RODATA_AREA(p) (((const char *)p) >= RODATA_START_ADDRESS && ((const char *)p) <= RODATA_END_ADDRESS)
|
|
|
|
#endif /* defined(LUA_CROSS_COMPILER) */
|
|
|
|
/* Return 1 if the given pointer is a rotable */
|
|
#define luaR_isrotable(p) IN_RODATA_AREA(p)
|
|
|
|
#endif
|