Commit 17df207a authored by Johny Mattsson's avatar Johny Mattsson
Browse files

Port Terry's Lua 5.1 + 5.3 work from the esp8266 branch.

Changes have been kept to a minimum, but a serious chunk of work was
needed to move from 8266isms to IDFisms.

Some things got refactored into components/lua/common, in particular
the LFS location awareness.

As part of this work I also evicted our partition table manipulation
code, as with the current IDF it kept breaking checksums and rendering
things unbootable, which is the opposite of helpful (which was the
original intent behind it).

The uart module got relocated from base_nodemcu to the modules component
properly, after I worked out how to force its inclusion using Kconfig alone.
parent f123d462
......@@ -17,7 +17,7 @@
/* tags for values visible from Lua */
#define LAST_TAG LUA_TTHREAD
#define NUM_TAGS (LAST_TAG+1)
#define LUA_NUMTAGS (LAST_TAG+1)
#define READONLYMASK (1<<7) /* denormalised bitmask for READONLYBIT and */
#define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */
......@@ -28,15 +28,18 @@
#define LUA_TUPVAL (LAST_TAG+2)
#define LUA_TDEADKEY (LAST_TAG+3)
#ifdef __XTENSA__
#ifdef LUA_USE_ESP8266
/*
** force aligned access to critical fields in Flash-based structures
** wo is the offset of aligned word in bytes 0,4,8,..
** bo is the field within the word in bits 0..31
**
** Note that this returns a lu_int32 as returning a byte can cause the
** gcc code generator to emit an extra extui instruction.
*/
#define GET_BYTE_FN(name,t,wo,bo) \
static inline lu_byte get ## name(void *o) { \
lu_byte res; /* extract named field */ \
static inline lu_int32 get ## name(void *o) { \
lu_int32 res; /* extract named field */ \
asm ("l32i %0, %1, " #wo "; extui %0, %0, " #bo ", 8;" : "=r"(res) : "r"(o) : );\
return res; }
#else
......@@ -49,14 +52,12 @@ static inline lu_byte get ## name(void *o) { return ((t *)o)->name; }
*/
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
*/
......@@ -93,43 +94,47 @@ typedef union {
#define TValuefields Value value; int tt
#define LUA_TVALUE_NIL {NULL}, LUA_TNIL
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#pragma pack(4)
#ifdef LUA_USE_ESP
# pragma pack(4)
#endif
typedef struct lua_TValue {
TValuefields;
} TValue;
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#pragma pack()
#ifdef LUA_USE_ESP
# pragma pack()
#endif
/* 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 ttistable(o) (ttnov(o) == LUA_TTABLE)
#define ttisrwtable(o) (type(o) == LUA_TTABLE)
#define ttisrotable(o) (ttype(o) & LUA_TISROTABLE)
#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)
#define ttisrotable(o) (ttype(o) == LUA_TROTABLE)
#define ttislightfunction(o) (ttype(o) == LUA_TLIGHTFUNCTION)
#define ttisclfunction(o) (ttype(o) == LUA_TFUNCTION)
#define ttisfunction(o) (ttnov(o) == LUA_TFUNCTION)
/* Macros to access values */
#define ttype(o) ((void) (o)->value, (o)->tt)
#define ttnov(o) ((void) (o)->value, ((o)->tt & LUA_TMASK))
#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
#define rvalue(o) check_exp(ttisrotable(o), (o)->value.p)
#define fvalue(o) check_exp(ttislightfunction(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 clvalue(o) check_exp(ttisclfunction(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)
......@@ -156,9 +161,6 @@ typedef struct lua_TValue {
#define setpvalue(obj,x) \
{ void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTUSERDATA; }
#define setrvalue(obj,x) \
{ void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TROTABLE; }
#define setfvalue(obj,x) \
{ void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTFUNCTION; }
......@@ -192,7 +194,7 @@ typedef struct lua_TValue {
#define sethvalue(L,obj,x) \
{ GCObject *i_x = cast(GCObject *, (x)); \
TValue *i_o=(obj); \
i_o->value.gc=i_x; i_o->tt=LUA_TTABLE; \
i_o->value.gc=i_x; i_o->tt=gettt(x); \
checkliveness(G(L),i_o); }
#define setptvalue(L,obj,x) \
......@@ -227,7 +229,7 @@ typedef struct lua_TValue {
#define setttype(obj, stt) ((void) (obj)->value, (obj)->tt = (stt))
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
#define iscollectable(o) (ttype(o) >= LUA_TSTRING && ttype(o) <= LUA_TMASK)
typedef TValue *StkId; /* index to stack elements */
......@@ -245,19 +247,10 @@ typedef union TString {
} tsv;
} TString;
#ifdef LUA_CROSS_COMPILER
#define isreadonly(o) (0)
#else
#define isreadonly(o) ((o).marked & READONLYMASK)
#endif
#define ts_isreadonly(ts) isreadonly((ts)->tsv)
#define getstr(ts) (ts_isreadonly(ts) ? \
cast(const char *, *(const char**)((ts) + 1)) : \
cast(const char *, (ts) + 1))
#define getstr(ts) cast(const char *, (ts) + 1)
#define svalue(o) getstr(rawtsvalue(o))
typedef union Udata {
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
......@@ -268,7 +261,12 @@ typedef union Udata {
} uv;
} Udata;
#ifdef LUA_CROSS_COMPILER
#define isreadonly(o) (0)
#else
#define isreadonly(o) (getmarked(o) & READONLYMASK)
#endif
#define islfs(o) (getmarked(o) & LFSMASK)
/*
......@@ -279,20 +277,13 @@ typedef struct Proto {
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
#ifdef LUA_OPTIMIZE_DEBUG
unsigned char *packedlineinfo;
#else
int *lineinfo; /* map from opcodes to source lines */
#endif
struct LocVar *locvars; /* information about local variables */
TString **upvalues; /* upvalue names */
TString *source;
int sizeupvalues;
int sizek; /* size of `k' */
int sizecode;
#ifndef LUA_OPTIMIZE_DEBUG
int sizelineinfo;
#endif
int sizep; /* size of `p' */
int sizelocvars;
int linedefined;
......@@ -303,7 +294,6 @@ typedef struct Proto {
lu_byte is_vararg;
lu_byte maxstacksize;
} Proto;
#define proto_isreadonly(p) isreadonly(*(p))
/* masks for new-style vararg */
......@@ -373,6 +363,18 @@ typedef union Closure {
** Tables
*/
/*
** Common Table fields for both table versions (like CommonHeader in
** macro form, to be included in table structure definitions).
**
** Note that the sethvalue() macro works much like the setsvalue()
** macro and handles the abstracted type. the hvalue(o) macro can be
** used to access CommonTable fields and rw Table fields
*/
#define CommonTable CommonHeader; \
lu_byte flags; lu_byte lsizenode; struct Table *metatable
typedef union TKey {
struct {
TValuefields;
......@@ -390,10 +392,7 @@ typedef struct Node {
typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
CommonTable;
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
......@@ -401,7 +400,23 @@ typedef struct Table {
int sizearray; /* size of `array' array */
} Table;
typedef const struct luaR_entry ROTable;
GET_BYTE_FN(flags,Table,4,16)
GET_BYTE_FN(lsizenode,Table,4,24)
typedef const struct ROTable_entry {
const char *key;
const TValue value;
} ROTable_entry;
typedef struct ROTable {
/* next always has the value (GCObject *)((size_t) 1); */
/* flags & 1<<p means tagmethod(p) is not present */
/* lsizenode is unused */
/* Like TStrings, the ROTable_entry vector follows the ROTable */
CommonTable;
ROTable_entry *entry;
} ROTable;
/*
** `module' operation for hashing (size is always a power of 2)
......
......@@ -6,9 +6,7 @@
#define lopcodes_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include "lopcodes.h"
/* ORDER OP */
......
......@@ -7,7 +7,6 @@
#define lparser_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
......@@ -344,12 +343,10 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->bl = NULL;
f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */
#ifdef LUA_OPTIMIZE_DEBUG
fs->packedlineinfoSize = 0;
fs->lastline = 0;
fs->lastlineOffset = 0;
fs->lineinfoLastPC = -1;
#endif
fs->h = luaH_new(L, 0, 0);
/* anchor table of constants and prototype (to avoid being collected) */
sethvalue2s(L, L->top, fs->h);
......@@ -367,15 +364,9 @@ static void close_func (LexState *ls) {
luaK_ret(fs, 0, 0); /* final return */
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
f->sizecode = fs->pc;
#ifdef LUA_OPTIMIZE_DEBUG
f->packedlineinfo[fs->lastlineOffset+1]=0;
luaM_reallocvector(L, f->packedlineinfo, fs->packedlineinfoSize,
fs->lastlineOffset+2, unsigned char);
#else
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
f->sizelineinfo = fs->pc;
#endif
luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
f->sizek = fs->nk;
luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
......@@ -392,20 +383,11 @@ static void close_func (LexState *ls) {
L->top -= 2; /* remove table and prototype from the stack */
}
#ifdef LUA_OPTIMIZE_DEBUG
static void compile_stripdebug(lua_State *L, Proto *f) {
int level;
lua_pushlightuserdata(L, &luaG_stripdebug );
lua_gettable(L, LUA_REGISTRYINDEX);
level = lua_isnil(L, -1) ? LUA_OPTIMIZE_DEBUG : lua_tointeger(L, -1);
lua_pop(L, 1);
if (level > 1) {
int len = luaG_stripdebug(L, f, level, 1);
UNUSED(len);
}
int level = G(L)->stripdefault;
if (level > 0)
luaG_stripdebug(L, f, level, 1);
}
#endif
Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
......@@ -422,9 +404,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
chunk(&lexstate);
check(&lexstate, TK_EOS);
close_func(&lexstate);
#ifdef LUA_OPTIMIZE_DEBUG
compile_stripdebug(L, funcstate.f);
#endif
L->top--; /* remove 'name' from stack */
lua_assert(funcstate.prev == NULL);
lua_assert(funcstate.f->nups == 0);
......
......@@ -72,12 +72,10 @@ typedef struct FuncState {
lu_byte nactvar; /* number of active local variables */
upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
#ifdef LUA_OPTIMIZE_DEBUG
int packedlineinfoSize; /* only used during compilation for line info */
int lastline; /* ditto */
int lastlineOffset; /* ditto */
int lineinfoLastPC; /* ditto */
#endif
} FuncState;
......
......@@ -7,7 +7,6 @@
#define lstate_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
......@@ -185,6 +184,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->memlimit = 0;
g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL;
g->stripdefault = CONFIG_LUA_OPTIMIZE_DEBUG;
g->gcdept = 0;
#ifdef EGC_INITIAL_MODE
g->egcmode = EGC_INITIAL_MODE;
......@@ -202,8 +202,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->ROstrt.hash = NULL;
g->ROpvmain = NULL;
g->LFSsize = 0;
g->error_reporter = 0;
#endif
for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
for (i=0; i<LUA_NUMTAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
/* memory allocation error: free partial state */
close_state(L);
......@@ -229,9 +230,6 @@ lua_State *lua_open(void) {
return lua_crtstate;
}
lua_State *lua_getstate(void) {
return lua_crtstate;
}
LUA_API void lua_close (lua_State *L) {
#ifndef LUA_CROSS_COMPILER
lua_sethook( L, NULL, 0, 0 );
......
......@@ -56,7 +56,7 @@ typedef struct CallInfo {
#define curr_func(L) (ttisfunction(L->ci->func) ? clvalue(L->ci->func) : NULL)
#define curr_func(L) (ttisclfunction(L->ci->func) ? clvalue(L->ci->func) : NULL)
#define ci_func(ci) (ttisfunction((ci)->func) ? clvalue((ci)->func) : NULL)
#define f_isLua(ci) (!ttislightfunction((ci)->func) && !ci_func(ci)->c.isC)
#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
......@@ -87,17 +87,19 @@ typedef struct global_State {
lu_mem gcdept; /* how much GC is `behind schedule' */
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC `granularity' */
int stripdefault; /* default stripping level for compilation */
int egcmode; /* emergency garbage collection operation mode */
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 */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */
#ifndef LUA_CROSS_COMPILER
stringtable ROstrt; /* Flash-based hash table for RO strings */
Proto *ROpvmain; /* Flash-based Proto main */
int LFSsize; /* Size of Lua Flash Store */
int error_reporter; /* Registry Index of error reporter task */
#endif
} global_State;
......@@ -159,7 +161,7 @@ union GCObject {
#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 gco2h(o) check_exp(((o)->gch.tt & LUA_TMASK) == 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) \
......
......@@ -8,7 +8,6 @@
#define lstring_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
......@@ -18,8 +17,6 @@
#include "lstate.h"
#include "lstring.h"
#define LUAS_READONLY_STRING 1
#define LUAS_REGULAR_STRING 0
void luaS_resize (lua_State *L, int newsize) {
stringtable *tb;
......@@ -53,26 +50,20 @@ void luaS_resize (lua_State *L, int newsize) {
}
static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h, int readonly) {
unsigned int h) {
TString *ts;
stringtable *tb;
stringtable *tb = &G(L)->strt;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
tb = &G(L)->strt;
if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */
ts = cast(TString *, luaM_malloc(L, sizeof(TString) + (readonly ? sizeof(char**) : (l+1)*sizeof(char))));
ts = cast(TString *, luaM_malloc(L, sizeof(TString) + (l+1)*sizeof(char)));
ts->tsv.len = l;
ts->tsv.hash = h;
ts->tsv.marked = luaC_white(G(L));
ts->tsv.tt = LUA_TSTRING;
if (!readonly) {
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else {
*(char **)(ts+1) = (char *)str;
l_setbit((ts)->tsv.marked, READONLYBIT);
}
h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */
tb->hash[h] = obj2gco(ts);
......@@ -80,15 +71,6 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return ts;
}
static int lua_is_ptr_in_ro_area(const char *p) {
#ifdef LUA_CROSS_COMPILER
(void)p;
return 0; // TStrings are never in RO in luac.cross
#else
return IN_RODATA_AREA(p);
#endif
}
/*
* The string algorithm has been modified to be LFS-friendly. The previous eLua
* algo used the address of the string was in flash and the string was >4 bytes
......@@ -129,11 +111,7 @@ LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
}
}
#endif
/* New additions to the RAM strt are tagged as readonly if the string address
* is in the CTEXT segment (target only, not luac.cross) */
int readonly = (lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) &&
l == strlen(str) ? LUAS_READONLY_STRING : LUAS_REGULAR_STRING);
return newlstr(L, str, l, h, readonly); /* not found */
return newlstr(L, str, l, h); /* not found */
}
......
......@@ -13,8 +13,7 @@
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+(testbit(getmarked(s), READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#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)))
......
......@@ -7,7 +7,6 @@
#define lstrlib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
......@@ -15,13 +14,11 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.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);
......@@ -143,17 +140,25 @@ static int writer (lua_State *L, const void* b, size_t size, void* B) {
static int str_dump (lua_State *L) {
luaL_Buffer b;
int strip, tstrip = lua_type(L, 2);
if (tstrip == LUA_TBOOLEAN) {
strip = lua_toboolean(L, 2) ? 2 : 0;
} else if (tstrip == LUA_TNONE || tstrip == LUA_TNIL) {
strip = -1; /* This tells lua_dump to use the global strip default */
} else {
strip = lua_tointeger(L, 2);
luaL_argcheck(L, (unsigned)(strip) < 3, 2, "strip out of range");
}
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 1);
luaL_buffinit(L,&b);
if (lua_dump(L, writer, &b) != 0)
luaL_error(L, "unable to dump given function");
if (lua_dump(L, writer, &b, strip) != 0)
return luaL_error(L, "unable to dump given function");
luaL_pushresult(&b);
return 1;
}
/*
** {======================================================
** PATTERN MATCHING
......@@ -825,7 +830,21 @@ static int str_format (lua_State *L) {
return 1;
}
LROT_PUBLIC_BEGIN(strlib)
static int str_format2 (lua_State *L) {
if (lua_type(L, 2) == LUA_TTABLE) {
int i,n=lua_objlen(L,2);
lua_settop(L,2);
for (i = 1; i <= n; i++)
lua_rawgeti(L, 2, i);
lua_remove(L, 2);
}
return str_format(L);
}
LROT_BEGIN(strlib, NULL, LROT_MASK_INDEX)
LROT_TABENTRY( __index, strlib )
LROT_FUNCENTRY( __mod, str_format2 )
LROT_FUNCENTRY( byte, str_byte )
LROT_FUNCENTRY( char, str_char )
LROT_FUNCENTRY( dump, str_dump )
......@@ -845,8 +864,7 @@ LROT_PUBLIC_BEGIN(strlib)
LROT_FUNCENTRY( reverse, str_reverse )
LROT_FUNCENTRY( sub, str_sub )
LROT_FUNCENTRY( upper, str_upper )
LROT_TABENTRY( __index, strlib )
LROT_END(strlib, NULL, 0) // OR DO WE NEED LRTO_MASK_INDEX **TODO**
LROT_END(strlib, NULL, LROT_MASK_INDEX)
/*
** Open string library
......
......@@ -16,26 +16,24 @@
#define gnext(n) ((n)->i_key.nk.next)
#define key2tval(n) (&(n)->i_key.tvk)
#define isrotable(t) (gettt(t)==LUA_TROTABLE)
#define isrwtable(t) (gettt(t)==LUA_TTABLE)
LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
LUAI_FUNC const TValue *luaH_getnum_ro (void *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 const TValue *luaH_getstr_ro (void *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 const TValue *luaH_get_ro (void *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_next_ro (lua_State *L, void *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);
LUAI_FUNC int luaH_getn_ro (void *t);
LUAI_FUNC int luaH_isdummy (Node *n);
#define LUA_MAX_ROTABLE_NAME 32
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
#endif
......
......@@ -7,13 +7,11 @@
#define ltablib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
......@@ -22,7 +20,7 @@
static int foreachi (lua_State *L) {
int i;
int n = aux_getn(L, 1);
luaL_checkanyfunction(L, 2);
luaL_checkfunction(L, 2);
for (i=1; i <= n; i++) {
lua_pushvalue(L, 2); /* function */
lua_pushinteger(L, i); /* 1st argument */
......@@ -38,7 +36,7 @@ static int foreachi (lua_State *L) {
static int foreach (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanyfunction(L, 2);
luaL_checkfunction(L, 2);
lua_pushnil(L); /* first key */
while (lua_next(L, 1)) {
lua_pushvalue(L, 2); /* function */
......@@ -266,7 +264,7 @@ static int sort (lua_State *L) {
/* }====================================================== */
LROT_PUBLIC_BEGIN(tab_funcs)
LROT_BEGIN(tab_funcs, NULL, 0)
LROT_FUNCENTRY( concat, tconcat )
LROT_FUNCENTRY( foreach, foreach )
LROT_FUNCENTRY( foreachi, foreachi )
......
......@@ -5,37 +5,35 @@
*/
#include <string.h>
#define ltm_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
#include "lobject.h"
#include "lstate.h"
#include "lgc.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lrotable.h"
/* These must be correspond to the LUA_T* defines in lua.h */
const char *const luaT_typenames[] = {
"nil", "boolean", "romtable", "lightfunction", "userdata", "number",
"string", "table", "function", "userdata", "thread",
"nil", "boolean", "lightfunction","number", // base type = 0, 1, 2, 3
"string", "table", "function", "userdata", "thread", // base type = 4, 5, 6, 7, 8
"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"
"__concat", "__call",
"__metatable"
};
int i;
for (i=0; i<TM_N; i++) {
......@@ -50,22 +48,14 @@ void luaT_init (lua_State *L) {
** tag methods
*/
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm;
const TValue *tm = luaH_getstr(events, ename);
lua_assert(event <= TM_EQ);
if (luaR_isrotable(events)) {
tm = luaH_getstr_ro(events, ename);
if (ttisnil(tm)) { /* no tag method? */
if (isrwtable(events)) /* if this a (RW) Table */
events->flags |= cast_byte(1u<<event); /* then cache this fact */
return NULL;
}
} else {
tm = luaH_getstr(events, ename);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= cast_byte(1u<<event); /* cache this fact */
return NULL;
}
}
return tm;
else return tm;
}
......@@ -73,21 +63,14 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
switch (ttype(o)) {
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(o));
mt = hvalue(o)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(o)->metatable;
break;
default:
mt = G(L)->mt[ttype(o)];
mt = G(L)->mt[ttnov(o)];
}
if (!mt)
return luaO_nilobject;
else if (luaR_isrotable(mt))
return luaH_getstr_ro(mt, G(L)->tmname[event]);
else
return luaH_getstr(mt, G(L)->tmname[event]);
return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
}
......@@ -7,10 +7,6 @@
#ifndef ltm_h
#define ltm_h
#include "lobject.h"
#include "lrotable.h"
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM"
......@@ -33,11 +29,14 @@ typedef enum {
TM_LE,
TM_CONCAT,
TM_CALL,
TM_METATABLE,
TM_N /* number of elements in the enum */
} TMS;
//#include "lobject.h"
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
(!luaR_isrotable(et) && ((et)->flags & (1u<<(e)))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
(getflags(et) & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
#define fasttm(l,et,e) gfasttm(G(l), et, e)
......
#include "llimits.h"
#include "lauxlib.h"
#include "lualib.h"
#define LUA_VERSION_51
#include "../lua-5.3/lua.c"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment