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 @@ ...@@ -17,7 +17,7 @@
/* tags for values visible from Lua */ /* tags for values visible from Lua */
#define LAST_TAG LUA_TTHREAD #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 READONLYMASK (1<<7) /* denormalised bitmask for READONLYBIT and */
#define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */ #define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */
...@@ -28,15 +28,18 @@ ...@@ -28,15 +28,18 @@
#define LUA_TUPVAL (LAST_TAG+2) #define LUA_TUPVAL (LAST_TAG+2)
#define LUA_TDEADKEY (LAST_TAG+3) #define LUA_TDEADKEY (LAST_TAG+3)
#ifdef __XTENSA__ #ifdef LUA_USE_ESP8266
/* /*
** force aligned access to critical fields in Flash-based structures ** force aligned access to critical fields in Flash-based structures
** wo is the offset of aligned word in bytes 0,4,8,.. ** wo is the offset of aligned word in bytes 0,4,8,..
** bo is the field within the word in bits 0..31 ** 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) \ #define GET_BYTE_FN(name,t,wo,bo) \
static inline lu_byte get ## name(void *o) { \ static inline lu_int32 get ## name(void *o) { \
lu_byte res; /* extract named field */ \ lu_int32 res; /* extract named field */ \
asm ("l32i %0, %1, " #wo "; extui %0, %0, " #bo ", 8;" : "=r"(res) : "r"(o) : );\ asm ("l32i %0, %1, " #wo "; extui %0, %0, " #bo ", 8;" : "=r"(res) : "r"(o) : );\
return res; } return res; }
#else #else
...@@ -49,14 +52,12 @@ static inline lu_byte get ## name(void *o) { return ((t *)o)->name; } ...@@ -49,14 +52,12 @@ static inline lu_byte get ## name(void *o) { return ((t *)o)->name; }
*/ */
typedef union GCObject GCObject; typedef union GCObject GCObject;
/* /*
** Common Header for all collectable objects (in macro form, to be ** Common Header for all collectable objects (in macro form, to be
** included in other objects) ** included in other objects)
*/ */
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked #define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/* /*
** Common header in struct form ** Common header in struct form
*/ */
...@@ -93,43 +94,47 @@ typedef union { ...@@ -93,43 +94,47 @@ typedef union {
#define TValuefields Value value; int tt #define TValuefields Value value; int tt
#define LUA_TVALUE_NIL {NULL}, LUA_TNIL #define LUA_TVALUE_NIL {NULL}, LUA_TNIL
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER) #ifdef LUA_USE_ESP
#pragma pack(4) # pragma pack(4)
#endif #endif
typedef struct lua_TValue { typedef struct lua_TValue {
TValuefields; TValuefields;
} TValue; } TValue;
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#pragma pack() #ifdef LUA_USE_ESP
# pragma pack()
#endif #endif
/* Macros to test type */ /* 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 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 ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
#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 ttislightfunction(o) (ttype(o) == LUA_TLIGHTFUNCTION)
#define ttisclfunction(o) (ttype(o) == LUA_TFUNCTION)
#define ttisfunction(o) (ttnov(o) == LUA_TFUNCTION)
/* Macros to access values */ /* Macros to access values */
#define ttype(o) ((void) (o)->value, (o)->tt) #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 gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) #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 fvalue(o) check_exp(ttislightfunction(o), (o)->value.p)
#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) #define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
#define tsvalue(o) (&rawtsvalue(o)->tsv) #define tsvalue(o) (&rawtsvalue(o)->tsv)
#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
#define uvalue(o) (&rawuvalue(o)->uv) #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 hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) #define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) #define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
...@@ -156,9 +161,6 @@ typedef struct lua_TValue { ...@@ -156,9 +161,6 @@ typedef struct lua_TValue {
#define setpvalue(obj,x) \ #define setpvalue(obj,x) \
{ void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTUSERDATA; } { 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) \ #define setfvalue(obj,x) \
{ void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTFUNCTION; } { 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 { ...@@ -192,7 +194,7 @@ typedef struct lua_TValue {
#define sethvalue(L,obj,x) \ #define sethvalue(L,obj,x) \
{ GCObject *i_x = cast(GCObject *, (x)); \ { GCObject *i_x = cast(GCObject *, (x)); \
TValue *i_o=(obj); \ 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); } checkliveness(G(L),i_o); }
#define setptvalue(L,obj,x) \ #define setptvalue(L,obj,x) \
...@@ -227,7 +229,7 @@ typedef struct lua_TValue { ...@@ -227,7 +229,7 @@ typedef struct lua_TValue {
#define setttype(obj, stt) ((void) (obj)->value, (obj)->tt = (stt)) #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 */ typedef TValue *StkId; /* index to stack elements */
...@@ -245,19 +247,10 @@ typedef union TString { ...@@ -245,19 +247,10 @@ typedef union TString {
} tsv; } tsv;
} TString; } TString;
#ifdef LUA_CROSS_COMPILER #define getstr(ts) cast(const char *, (ts) + 1)
#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 svalue(o) getstr(rawtsvalue(o)) #define svalue(o) getstr(rawtsvalue(o))
typedef union Udata { typedef union Udata {
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct { struct {
...@@ -268,7 +261,12 @@ typedef union Udata { ...@@ -268,7 +261,12 @@ typedef union Udata {
} uv; } uv;
} Udata; } 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 { ...@@ -279,20 +277,13 @@ typedef struct Proto {
TValue *k; /* constants used by the function */ TValue *k; /* constants used by the function */
Instruction *code; Instruction *code;
struct Proto **p; /* functions defined inside the function */ struct Proto **p; /* functions defined inside the function */
#ifdef LUA_OPTIMIZE_DEBUG
unsigned char *packedlineinfo; unsigned char *packedlineinfo;
#else
int *lineinfo; /* map from opcodes to source lines */
#endif
struct LocVar *locvars; /* information about local variables */ struct LocVar *locvars; /* information about local variables */
TString **upvalues; /* upvalue names */ TString **upvalues; /* upvalue names */
TString *source; TString *source;
int sizeupvalues; int sizeupvalues;
int sizek; /* size of `k' */ int sizek; /* size of `k' */
int sizecode; int sizecode;
#ifndef LUA_OPTIMIZE_DEBUG
int sizelineinfo;
#endif
int sizep; /* size of `p' */ int sizep; /* size of `p' */
int sizelocvars; int sizelocvars;
int linedefined; int linedefined;
...@@ -303,7 +294,6 @@ typedef struct Proto { ...@@ -303,7 +294,6 @@ typedef struct Proto {
lu_byte is_vararg; lu_byte is_vararg;
lu_byte maxstacksize; lu_byte maxstacksize;
} Proto; } Proto;
#define proto_isreadonly(p) isreadonly(*(p))
/* masks for new-style vararg */ /* masks for new-style vararg */
...@@ -373,6 +363,18 @@ typedef union Closure { ...@@ -373,6 +363,18 @@ typedef union Closure {
** Tables ** 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 { typedef union TKey {
struct { struct {
TValuefields; TValuefields;
...@@ -390,10 +392,7 @@ typedef struct Node { ...@@ -390,10 +392,7 @@ typedef struct Node {
typedef struct Table { typedef struct Table {
CommonHeader; CommonTable;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
TValue *array; /* array part */ TValue *array; /* array part */
Node *node; Node *node;
Node *lastfree; /* any free position is before this position */ Node *lastfree; /* any free position is before this position */
...@@ -401,7 +400,23 @@ typedef struct Table { ...@@ -401,7 +400,23 @@ typedef struct Table {
int sizearray; /* size of `array' array */ int sizearray; /* size of `array' array */
} Table; } 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) ** `module' operation for hashing (size is always a power of 2)
......
...@@ -6,9 +6,7 @@ ...@@ -6,9 +6,7 @@
#define lopcodes_c #define lopcodes_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include "lopcodes.h" #include "lopcodes.h"
/* ORDER OP */ /* ORDER OP */
......
...@@ -186,8 +186,8 @@ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ ...@@ -186,8 +186,8 @@ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
...@@ -197,8 +197,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2); ...@@ -197,8 +197,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */ if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
...@@ -240,7 +240,7 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ ...@@ -240,7 +240,7 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
** bits 4-5: B arg mode ** bits 4-5: B arg mode
** bit 6: instruction set register A ** bit 6: instruction set register A
** bit 7: operator is a test ** bit 7: operator is a test
*/ */
enum OpArgMask { enum OpArgMask {
OpArgN, /* argument is not used */ OpArgN, /* argument is not used */
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#define lparser_c #define lparser_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <string.h> #include <string.h>
...@@ -344,12 +343,10 @@ static void open_func (LexState *ls, FuncState *fs) { ...@@ -344,12 +343,10 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->bl = NULL; fs->bl = NULL;
f->source = ls->source; f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */ f->maxstacksize = 2; /* registers 0/1 are always valid */
#ifdef LUA_OPTIMIZE_DEBUG
fs->packedlineinfoSize = 0; fs->packedlineinfoSize = 0;
fs->lastline = 0; fs->lastline = 0;
fs->lastlineOffset = 0; fs->lastlineOffset = 0;
fs->lineinfoLastPC = -1; fs->lineinfoLastPC = -1;
#endif
fs->h = luaH_new(L, 0, 0); fs->h = luaH_new(L, 0, 0);
/* anchor table of constants and prototype (to avoid being collected) */ /* anchor table of constants and prototype (to avoid being collected) */
sethvalue2s(L, L->top, fs->h); sethvalue2s(L, L->top, fs->h);
...@@ -367,15 +364,9 @@ static void close_func (LexState *ls) { ...@@ -367,15 +364,9 @@ static void close_func (LexState *ls) {
luaK_ret(fs, 0, 0); /* final return */ luaK_ret(fs, 0, 0); /* final return */
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
f->sizecode = fs->pc; f->sizecode = fs->pc;
#ifdef LUA_OPTIMIZE_DEBUG
f->packedlineinfo[fs->lastlineOffset+1]=0; f->packedlineinfo[fs->lastlineOffset+1]=0;
luaM_reallocvector(L, f->packedlineinfo, fs->packedlineinfoSize, luaM_reallocvector(L, f->packedlineinfo, fs->packedlineinfoSize,
fs->lastlineOffset+2, unsigned char); 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); luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
f->sizek = fs->nk; f->sizek = fs->nk;
luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
...@@ -392,20 +383,11 @@ static void close_func (LexState *ls) { ...@@ -392,20 +383,11 @@ static void close_func (LexState *ls) {
L->top -= 2; /* remove table and prototype from the stack */ L->top -= 2; /* remove table and prototype from the stack */
} }
#ifdef LUA_OPTIMIZE_DEBUG
static void compile_stripdebug(lua_State *L, Proto *f) { static void compile_stripdebug(lua_State *L, Proto *f) {
int level; int level = G(L)->stripdefault;
lua_pushlightuserdata(L, &luaG_stripdebug ); if (level > 0)
lua_gettable(L, LUA_REGISTRYINDEX); luaG_stripdebug(L, f, level, 1);
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);
}
} }
#endif
Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { 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) { ...@@ -422,9 +404,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
chunk(&lexstate); chunk(&lexstate);
check(&lexstate, TK_EOS); check(&lexstate, TK_EOS);
close_func(&lexstate); close_func(&lexstate);
#ifdef LUA_OPTIMIZE_DEBUG
compile_stripdebug(L, funcstate.f); compile_stripdebug(L, funcstate.f);
#endif
L->top--; /* remove 'name' from stack */ L->top--; /* remove 'name' from stack */
lua_assert(funcstate.prev == NULL); lua_assert(funcstate.prev == NULL);
lua_assert(funcstate.f->nups == 0); lua_assert(funcstate.f->nups == 0);
......
...@@ -72,12 +72,10 @@ typedef struct FuncState { ...@@ -72,12 +72,10 @@ typedef struct FuncState {
lu_byte nactvar; /* number of active local variables */ lu_byte nactvar; /* number of active local variables */
upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
#ifdef LUA_OPTIMIZE_DEBUG
int packedlineinfoSize; /* only used during compilation for line info */ int packedlineinfoSize; /* only used during compilation for line info */
int lastline; /* ditto */ int lastline; /* ditto */
int lastlineOffset; /* ditto */ int lastlineOffset; /* ditto */
int lineinfoLastPC; /* ditto */ int lineinfoLastPC; /* ditto */
#endif
} FuncState; } FuncState;
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#define lstate_c #define lstate_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
...@@ -35,7 +34,7 @@ typedef struct LG { ...@@ -35,7 +34,7 @@ typedef struct LG {
lua_State l; lua_State l;
global_State g; global_State g;
} LG; } LG;
static void stack_init (lua_State *L1, lua_State *L) { static void stack_init (lua_State *L1, lua_State *L) {
...@@ -185,6 +184,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { ...@@ -185,6 +184,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->memlimit = 0; g->memlimit = 0;
g->gcpause = LUAI_GCPAUSE; g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL; g->gcstepmul = LUAI_GCMUL;
g->stripdefault = CONFIG_LUA_OPTIMIZE_DEBUG;
g->gcdept = 0; g->gcdept = 0;
#ifdef EGC_INITIAL_MODE #ifdef EGC_INITIAL_MODE
g->egcmode = EGC_INITIAL_MODE; g->egcmode = EGC_INITIAL_MODE;
...@@ -197,13 +197,14 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { ...@@ -197,13 +197,14 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->memlimit = 0; g->memlimit = 0;
#endif #endif
#ifndef LUA_CROSS_COMPILER #ifndef LUA_CROSS_COMPILER
g->ROstrt.size = 0; g->ROstrt.size = 0;
g->ROstrt.nuse = 0; g->ROstrt.nuse = 0;
g->ROstrt.hash = NULL; g->ROstrt.hash = NULL;
g->ROpvmain = NULL; g->ROpvmain = NULL;
g->LFSsize = 0; g->LFSsize = 0;
g->error_reporter = 0;
#endif #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) { if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
/* memory allocation error: free partial state */ /* memory allocation error: free partial state */
close_state(L); close_state(L);
...@@ -225,20 +226,17 @@ extern lua_State *luaL_newstate (void); ...@@ -225,20 +226,17 @@ extern lua_State *luaL_newstate (void);
static lua_State *lua_crtstate; static lua_State *lua_crtstate;
lua_State *lua_open(void) { lua_State *lua_open(void) {
lua_crtstate = luaL_newstate(); lua_crtstate = luaL_newstate();
return lua_crtstate; return lua_crtstate;
} }
lua_State *lua_getstate(void) {
return lua_crtstate;
}
LUA_API void lua_close (lua_State *L) { LUA_API void lua_close (lua_State *L) {
#ifndef LUA_CROSS_COMPILER #ifndef LUA_CROSS_COMPILER
lua_sethook( L, NULL, 0, 0 ); lua_sethook( L, NULL, 0, 0 );
lua_crtstate = NULL; lua_crtstate = NULL;
lua_pushnil( L ); lua_pushnil( L );
// lua_rawseti( L, LUA_REGISTRYINDEX, LUA_INT_HANDLER_KEY ); // lua_rawseti( L, LUA_REGISTRYINDEX, LUA_INT_HANDLER_KEY );
#endif #endif
L = G(L)->mainthread; /* only the main thread can be closed */ L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L); lua_lock(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */ luaF_close(L, L->stack); /* close all upvalues for this thread */
......
...@@ -56,7 +56,7 @@ typedef struct CallInfo { ...@@ -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 ci_func(ci) (ttisfunction((ci)->func) ? clvalue((ci)->func) : NULL)
#define f_isLua(ci) (!ttislightfunction((ci)->func) && !ci_func(ci)->c.isC) #define f_isLua(ci) (!ttislightfunction((ci)->func) && !ci_func(ci)->c.isC)
#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) #define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
...@@ -87,17 +87,19 @@ typedef struct global_State { ...@@ -87,17 +87,19 @@ typedef struct global_State {
lu_mem gcdept; /* how much GC is `behind schedule' */ lu_mem gcdept; /* how much GC is `behind schedule' */
int gcpause; /* size of pause between successive GCs */ int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC `granularity' */ int gcstepmul; /* GC `granularity' */
int stripdefault; /* default stripping level for compilation */
int egcmode; /* emergency garbage collection operation mode */ int egcmode; /* emergency garbage collection operation mode */
lua_CFunction panic; /* to be called in unprotected errors */ lua_CFunction panic; /* to be called in unprotected errors */
TValue l_registry; TValue l_registry;
struct lua_State *mainthread; struct lua_State *mainthread;
UpVal uvhead; /* head of double-linked list of all open upvalues */ 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 */ TString *tmname[TM_N]; /* array with tag-method names */
#ifndef LUA_CROSS_COMPILER #ifndef LUA_CROSS_COMPILER
stringtable ROstrt; /* Flash-based hash table for RO strings */ stringtable ROstrt; /* Flash-based hash table for RO strings */
Proto *ROpvmain; /* Flash-based Proto main */ Proto *ROpvmain; /* Flash-based Proto main */
int LFSsize; /* Size of Lua Flash Store */ int LFSsize; /* Size of Lua Flash Store */
int error_reporter; /* Registry Index of error reporter task */
#endif #endif
} global_State; } global_State;
...@@ -159,7 +161,7 @@ union GCObject { ...@@ -159,7 +161,7 @@ union GCObject {
#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
#define gco2u(o) (&rawgco2u(o)->uv) #define gco2u(o) (&rawgco2u(o)->uv)
#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) #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 gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
#define ngcotouv(o) \ #define ngcotouv(o) \
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#define lstring_c #define lstring_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <string.h> #include <string.h>
...@@ -18,8 +17,6 @@ ...@@ -18,8 +17,6 @@
#include "lstate.h" #include "lstate.h"
#include "lstring.h" #include "lstring.h"
#define LUAS_READONLY_STRING 1
#define LUAS_REGULAR_STRING 0
void luaS_resize (lua_State *L, int newsize) { void luaS_resize (lua_State *L, int newsize) {
stringtable *tb; stringtable *tb;
...@@ -53,26 +50,20 @@ void luaS_resize (lua_State *L, int newsize) { ...@@ -53,26 +50,20 @@ void luaS_resize (lua_State *L, int newsize) {
} }
static TString *newlstr (lua_State *L, const char *str, size_t l, static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h, int readonly) { unsigned int h) {
TString *ts; TString *ts;
stringtable *tb; stringtable *tb = &G(L)->strt;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L); luaM_toobig(L);
tb = &G(L)->strt;
if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */ 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.len = l;
ts->tsv.hash = h; ts->tsv.hash = h;
ts->tsv.marked = luaC_white(G(L)); ts->tsv.marked = luaC_white(G(L));
ts->tsv.tt = LUA_TSTRING; ts->tsv.tt = LUA_TSTRING;
if (!readonly) { memcpy(ts+1, str, l*sizeof(char));
memcpy(ts+1, str, l*sizeof(char)); ((char *)(ts+1))[l] = '\0'; /* ending 0 */
((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else {
*(char **)(ts+1) = (char *)str;
l_setbit((ts)->tsv.marked, READONLYBIT);
}
h = lmod(h, tb->size); h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */ ts->tsv.next = tb->hash[h]; /* chain new entry */
tb->hash[h] = obj2gco(ts); tb->hash[h] = obj2gco(ts);
...@@ -80,15 +71,6 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, ...@@ -80,15 +71,6 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return ts; 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 * 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 * 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) { ...@@ -129,11 +111,7 @@ LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
} }
} }
#endif #endif
/* New additions to the RAM strt are tagged as readonly if the string address return newlstr(L, str, l, h); /* not found */
* 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 */
} }
......
...@@ -13,8 +13,7 @@ ...@@ -13,8 +13,7 @@
#include "lstate.h" #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 sizeudata(u) (sizeof(union Udata)+(u)->len)
#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#define lstrlib_c #define lstrlib_c
#define LUA_LIB #define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <stdio.h> #include <stdio.h>
...@@ -15,13 +14,11 @@ ...@@ -15,13 +14,11 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
/* macro to `unsign' a character */ /* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c)) #define uchar(c) ((unsigned char)(c))
static int str_len (lua_State *L) { static int str_len (lua_State *L) {
size_t l; size_t l;
luaL_checklstring(L, 1, &l); luaL_checklstring(L, 1, &l);
...@@ -143,17 +140,25 @@ static int writer (lua_State *L, const void* b, size_t size, void* B) { ...@@ -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) { static int str_dump (lua_State *L) {
luaL_Buffer b; 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); luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 1); lua_settop(L, 1);
luaL_buffinit(L,&b); luaL_buffinit(L,&b);
if (lua_dump(L, writer, &b) != 0) if (lua_dump(L, writer, &b, strip) != 0)
luaL_error(L, "unable to dump given function"); return luaL_error(L, "unable to dump given function");
luaL_pushresult(&b); luaL_pushresult(&b);
return 1; return 1;
} }
/* /*
** {====================================================== ** {======================================================
** PATTERN MATCHING ** PATTERN MATCHING
...@@ -634,7 +639,7 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, ...@@ -634,7 +639,7 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
lua_pushlstring(L, s, e - s); /* keep original text */ lua_pushlstring(L, s, e - s); /* keep original text */
} }
else if (!lua_isstring(L, -1)) else if (!lua_isstring(L, -1))
luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
luaL_addvalue(b); /* add result to accumulator */ luaL_addvalue(b); /* add result to accumulator */
} }
...@@ -787,7 +792,7 @@ static int str_format (lua_State *L) { ...@@ -787,7 +792,7 @@ static int str_format (lua_State *L) {
sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
break; break;
} }
#if !defined LUA_NUMBER_INTEGRAL #if !defined LUA_NUMBER_INTEGRAL
case 'e': case 'E': case 'f': case 'e': case 'E': case 'f':
case 'g': case 'G': { case 'g': case 'G': {
sprintf(buff, form, (double)luaL_checknumber(L, arg)); sprintf(buff, form, (double)luaL_checknumber(L, arg));
...@@ -825,7 +830,21 @@ static int str_format (lua_State *L) { ...@@ -825,7 +830,21 @@ static int str_format (lua_State *L) {
return 1; 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( byte, str_byte )
LROT_FUNCENTRY( char, str_char ) LROT_FUNCENTRY( char, str_char )
LROT_FUNCENTRY( dump, str_dump ) LROT_FUNCENTRY( dump, str_dump )
...@@ -845,8 +864,7 @@ LROT_PUBLIC_BEGIN(strlib) ...@@ -845,8 +864,7 @@ LROT_PUBLIC_BEGIN(strlib)
LROT_FUNCENTRY( reverse, str_reverse ) LROT_FUNCENTRY( reverse, str_reverse )
LROT_FUNCENTRY( sub, str_sub ) LROT_FUNCENTRY( sub, str_sub )
LROT_FUNCENTRY( upper, str_upper ) LROT_FUNCENTRY( upper, str_upper )
LROT_TABENTRY( __index, strlib ) LROT_END(strlib, NULL, LROT_MASK_INDEX)
LROT_END(strlib, NULL, 0) // OR DO WE NEED LRTO_MASK_INDEX **TODO**
/* /*
** Open string library ** Open string library
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#define ltable_c #define ltable_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <math.h> #include <math.h>
...@@ -33,7 +32,8 @@ ...@@ -33,7 +32,8 @@
#include "lobject.h" #include "lobject.h"
#include "lstate.h" #include "lstate.h"
#include "ltable.h" #include "ltable.h"
#include "lrotable.h" #include "lstring.h"
/* /*
** max size of array part is 2^MAXBITS ** max size of array part is 2^MAXBITS
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) #define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
#define hashboolean(t,p) hashpow2(t, p) #define hashboolean(t,p) hashpow2(t, p)
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
*/ */
#define numints cast_int(sizeof(lua_Number)/sizeof(int)) #define numints cast_int(sizeof(lua_Number)/sizeof(int))
static const TValue* rotable_findentry(ROTable *rotable, TString *key, unsigned *ppos);
static void rotable_next_helper(lua_State *L, ROTable *pentries, int pos,
TValue *key, TValue *val);
static void rotable_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val);
#define dummynode (&dummynode_) #define dummynode (&dummynode_)
...@@ -105,11 +109,11 @@ static Node *mainposition (const Table *t, const TValue *key) { ...@@ -105,11 +109,11 @@ static Node *mainposition (const Table *t, const TValue *key) {
return hashstr(t, rawtsvalue(key)); return hashstr(t, rawtsvalue(key));
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key)); return hashboolean(t, bvalue(key));
case LUA_TROTABLE:
return hashpointer(t, rvalue(key));
case LUA_TLIGHTUSERDATA: case LUA_TLIGHTUSERDATA:
case LUA_TLIGHTFUNCTION: case LUA_TLIGHTFUNCTION:
return hashpointer(t, pvalue(key)); return hashpointer(t, pvalue(key));
case LUA_TROTABLE:
return hashpointer(t, hvalue(key));
default: default:
return hashpointer(t, gcvalue(key)); return hashpointer(t, gcvalue(key));
} }
...@@ -163,7 +167,12 @@ static int findindex (lua_State *L, Table *t, StkId key) { ...@@ -163,7 +167,12 @@ static int findindex (lua_State *L, Table *t, StkId key) {
int luaH_next (lua_State *L, Table *t, StkId key) { int luaH_next (lua_State *L, Table *t, StkId key) {
int i = findindex(L, t, key); /* find original element */ int i;
if (isrotable(t)) {
rotable_next(L, (ROTable *) t, key, key+1);
return ttisnil(key) ? 0 : 1;
}
i = findindex(L, t, key); /* find original element */
for (i++; i < t->sizearray; i++) { /* try first array part */ for (i++; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setnvalue(key, cast_num(i+1)); setnvalue(key, cast_num(i+1));
...@@ -182,12 +191,6 @@ int luaH_next (lua_State *L, Table *t, StkId key) { ...@@ -182,12 +191,6 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
} }
int luaH_next_ro (lua_State *L, void *t, StkId key) {
luaR_next(L, t, key, key+1);
return ttisnil(key) ? 0 : 1;
}
/* /*
** {============================================================= ** {=============================================================
** Rehash ** Rehash
...@@ -330,7 +333,7 @@ static Node *find_prev_node(Node *mp, Node *next) { ...@@ -330,7 +333,7 @@ static Node *find_prev_node(Node *mp, Node *next) {
** first, check whether the moving node's main position is free. If not, check whether ** first, check whether the moving node's main position is free. If not, check whether
** colliding node is in its main position or not: if it is not, move colliding ** colliding node is in its main position or not: if it is not, move colliding
** node to an empty place and put moving node in its main position; otherwise ** node to an empty place and put moving node in its main position; otherwise
** (colliding node is in its main position), moving node goes to an empty position. ** (colliding node is in its main position), moving node goes to an empty position.
*/ */
static int move_node (lua_State *L, Table *t, Node *node) { static int move_node (lua_State *L, Table *t, Node *node) {
(void)L; (void)L;
...@@ -372,7 +375,7 @@ static int move_node (lua_State *L, Table *t, Node *node) { ...@@ -372,7 +375,7 @@ static int move_node (lua_State *L, Table *t, Node *node) {
static int move_number (lua_State *L, Table *t, Node *node) { static int move_number (lua_State *L, Table *t, Node *node) {
(void)L; (void)t; (void)L;
int key; int key;
lua_Number n = nvalue(key2tval(node)); lua_Number n = nvalue(key2tval(node));
lua_number2int(key, n); lua_number2int(key, n);
...@@ -565,6 +568,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { ...@@ -565,6 +568,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
** search function for integers ** search function for integers
*/ */
const TValue *luaH_getnum (Table *t, int key) { const TValue *luaH_getnum (Table *t, int key) {
if (isrotable(t))
return luaO_nilobject;
/* (1 <= key && key <= t->sizearray) */ /* (1 <= key && key <= t->sizearray) */
if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
return &t->array[key-1]; return &t->array[key-1];
...@@ -580,18 +585,16 @@ const TValue *luaH_getnum (Table *t, int key) { ...@@ -580,18 +585,16 @@ const TValue *luaH_getnum (Table *t, int key) {
} }
} }
/* same thing for rotables */
const TValue *luaH_getnum_ro (void *t, int key) {
(void)t; (void)key;
const TValue *res = NULL; // integer values not supported: luaR_findentryN(t, key, NULL);
return res ? res : luaO_nilobject;
}
/* /*
** search function for strings ** search function for strings
*/ */
const TValue *luaH_getstr (Table *t, TString *key) { const TValue *luaH_getstr (Table *t, TString *key) {
if (isrotable(t)) {
if (key->tsv.len>LUA_MAX_ROTABLE_NAME)
return luaO_nilobject;
return rotable_findentry((ROTable*) t, key, NULL);
}
Node *n = hashstr(t, key); Node *n = hashstr(t, key);
do { /* check whether `key' is somewhere in the chain */ do { /* check whether `key' is somewhere in the chain */
if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
...@@ -601,65 +604,41 @@ const TValue *luaH_getstr (Table *t, TString *key) { ...@@ -601,65 +604,41 @@ const TValue *luaH_getstr (Table *t, TString *key) {
return luaO_nilobject; return luaO_nilobject;
} }
/* same thing for rotables */
const TValue *luaH_getstr_ro (void *t, TString *key) {
if (!t || key->tsv.len>LUA_MAX_ROTABLE_NAME)
return luaO_nilobject;
return luaR_findentry(t, key, NULL);
}
/* /*
** main search function ** main search function
*/ */
const TValue *luaH_get (Table *t, const TValue *key) { const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) { int type = ttype(key);
case LUA_TNIL: return luaO_nilobject; if (type == LUA_TNIL)
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); return luaO_nilobject;
case LUA_TNUMBER: { if (type == LUA_TSTRING)
int k; return luaH_getstr(t, rawtsvalue(key));
lua_Number n = nvalue(key); if (isrotable(t))
lua_number2int(k, n); return luaO_nilobject;
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ if (type == LUA_TNUMBER) {
return luaH_getnum(t, k); /* use specialized version */ int k;
/* else go through */ lua_Number n = nvalue(key);
} lua_number2int(k, n);
/* fall-through */ if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
default: { return luaH_getnum(t, k); /* use specialized version */
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key2tval(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
}
}
/* same thing for rotables */
const TValue *luaH_get_ro (void *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr_ro(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum_ro(t, k); /* use specialized version */
/* else go through */
}
/* fall-through */
default: {
return luaO_nilobject;
}
} }
/* default */
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key2tval(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
} }
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key); const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_get(t, key);
t->flags = 0; t->flags = 0;
if (p != luaO_nilobject) if (p != luaO_nilobject)
return cast(TValue *, p); return cast(TValue *, p);
...@@ -673,7 +652,10 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { ...@@ -673,7 +652,10 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
TValue *luaH_setnum (lua_State *L, Table *t, int key) { TValue *luaH_setnum (lua_State *L, Table *t, int key) {
const TValue *p = luaH_getnum(t, key); const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_getnum(t, key);
if (p != luaO_nilobject) if (p != luaO_nilobject)
return cast(TValue *, p); return cast(TValue *, p);
else { else {
...@@ -685,7 +667,10 @@ TValue *luaH_setnum (lua_State *L, Table *t, int key) { ...@@ -685,7 +667,10 @@ TValue *luaH_setnum (lua_State *L, Table *t, int key) {
TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
const TValue *p = luaH_getstr(t, key); const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_getstr(t, key);
if (p != luaO_nilobject) if (p != luaO_nilobject)
return cast(TValue *, p); return cast(TValue *, p);
else { else {
...@@ -725,7 +710,10 @@ static int unbound_search (Table *t, unsigned int j) { ...@@ -725,7 +710,10 @@ static int unbound_search (Table *t, unsigned int j) {
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/ */
int luaH_getn (Table *t) { int luaH_getn (Table *t) {
unsigned int j = t->sizearray; unsigned int j;
if(isrotable(t))
return 0;
j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) { if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */ /* there is a boundary in the array part: (binary) search for it */
unsigned int i = 0; unsigned int i = 0;
...@@ -742,14 +730,138 @@ int luaH_getn (Table *t) { ...@@ -742,14 +730,138 @@ int luaH_getn (Table *t) {
else return unbound_search(t, j); else return unbound_search(t, j);
} }
/* same thing for rotables */
int luaH_getn_ro (void *t) {
(void)t;
return 0; // Integer Keys are not currently supported for ROTables
}
int luaH_isdummy (Node *n) { return n == dummynode; } int luaH_isdummy (Node *n) { return n == dummynode; }
/*
** All keyed ROTable access passes through rotable_findentry(). ROTables
** are simply a list of <key><TValue value> pairs.
**
** The global KeyCache is used to avoid a relatively expensive Flash memory
** vector scan. A simple hash on the key's TString addr and the ROTable
** addr selects the cache line. The line's slots are then scanned for a
** hit.
**
** Unlike the standard hast which uses a prime line count therefore requires
** the use of modulus operation which is expensive on an IoT processor
** without H/W divide. This hash is power of 2 based which might not be
** quite so uniform but can be calcuated without using H/W-based instructions.
**
** If a match is found and the table addresses match, then this entry is
** probed first. In practice the hit-rate here is over 99% so the code
** rarely fails back to doing the linear scan in ROM.
** Note that this hash does a couple of prime multiples and a modulus 2^X
** with is all evaluated in H/W, and adequately randomizes the lookup.
*/
#define LA_LINES 32
#define LA_SLOTS 4
static size_t cache [LA_LINES][LA_SLOTS];
#define HASH(a,b) ((((29*(size_t)(a)) ^ (37*((b)->tsv.hash)))>>4) % LA_LINES)
#define NDX_SHFT 24
#define ADDR_MASK (((size_t) 1<<24)-1)
/*
* Find a string key entry in a rotable and return it. Note that this internally
* uses a null key to denote a metatable search.
*/
static const TValue* rotable_findentry(ROTable *t, TString *key, unsigned *ppos) {
const ROTable_entry *e = cast(const ROTable_entry *, t->entry);
const int tl = getlsizenode(t);
const char *strkey = getstr(key);
size_t *cl = cache[HASH(t, key)];
int i, j = 1, l;
if (!e || gettt(key) != LUA_TSTRING)
return luaO_nilobject;
l = key->tsv.len;
/* scan the ROTable lookaside cache and return if hit found */
for (i=0; i<LA_SLOTS; i++) {
int cl_ndx = cl[i] >> NDX_SHFT;
if ((((size_t)t - cl[i]) & ADDR_MASK) == 0 && cl_ndx < tl &&
strcmp(e[cl_ndx].key, strkey) == 0) {
if (ppos)
*ppos = cl_ndx;
return &e[cl_ndx].value;
}
}
/*
* A lot of search misses are metavalues, but tables typically only have at
* most a couple of them, so these are always put at the front of the table
* in ascending order and the metavalue scan short circuits using a straight
* strcmp()
*/
lu_int32 name4 = *(lu_int32 *) strkey;
if (*(char*)&name4 == '_') {
for(i = 0; i < tl; i++) {
j = strcmp(e[i].key, strkey);
if (j>=0)
break;
}
} else {
/*
* Ordinary (non-meta) keys can be unsorted. This is for legacy compatiblity,
* plus misses are pretty rare in this case. The masked name4 comparison is
* safe 4-byte comparison that nearly always avoids the more costly strcmp()
* for an actual hit validation.
*/
lu_int32 mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8);
for(i = 0; i < tl; i++) {
if (((*(lu_int32 *)e[i].key ^ name4) & mask4) != 0)
continue;
j = strcmp(e[i].key, strkey);
if (j==0)
break;
}
}
if (j)
return luaO_nilobject;
if (ppos)
*ppos = i;
/* In the case of a hit, update the lookaside cache */
for (j = LA_SLOTS-1; j>0; j--)
cl[j] = cl[j-1];
cl[0] = ((size_t)t & ADDR_MASK) + (i << NDX_SHFT);
return &e[i].value;
}
static void rotable_next_helper(lua_State *L, ROTable *t, int pos,
TValue *key, TValue *val) {
const ROTable_entry *e = cast(const ROTable_entry *, t->entry);
if (pos < getlsizenode(t)) {
/* Found an entry */
setsvalue(L, key, luaS_new(L, e[pos].key));
setobj2s(L, val, &e[pos].value);
} else {
setnilvalue(key);
setnilvalue(val);
}
}
/* next (used for iteration) */
static void rotable_next(lua_State *L, ROTable *t, TValue *key, TValue *val) {
unsigned keypos = getlsizenode(t);
/* Special case: if key is nil, return the first element of the rotable */
if (ttisnil(key))
rotable_next_helper(L, t, 0, key, val);
else if (ttisstring(key)) {
/* Find the previous key again */
if (ttisstring(key)) {
rotable_findentry(t, rawtsvalue(key), &keypos);
}
/* Advance to next key */
rotable_next_helper(L, t, ++keypos, key, val);
}
}
#if defined(LUA_DEBUG) #if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) { Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key); return mainposition(t, key);
......
...@@ -16,26 +16,24 @@ ...@@ -16,26 +16,24 @@
#define gnext(n) ((n)->i_key.nk.next) #define gnext(n) ((n)->i_key.nk.next)
#define key2tval(n) (&(n)->i_key.tvk) #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 (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 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 (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 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 (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 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 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_resizearray (lua_State *L, Table *t, int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t); 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 (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 (Table *t);
LUAI_FUNC int luaH_getn_ro (void *t);
LUAI_FUNC int luaH_isdummy (Node *n); LUAI_FUNC int luaH_isdummy (Node *n);
#define LUA_MAX_ROTABLE_NAME 32
#if defined(LUA_DEBUG) #if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
#endif #endif
......
...@@ -7,13 +7,11 @@ ...@@ -7,13 +7,11 @@
#define ltablib_c #define ltablib_c
#define LUA_LIB #define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "lrotable.h"
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
...@@ -22,7 +20,7 @@ ...@@ -22,7 +20,7 @@
static int foreachi (lua_State *L) { static int foreachi (lua_State *L) {
int i; int i;
int n = aux_getn(L, 1); int n = aux_getn(L, 1);
luaL_checkanyfunction(L, 2); luaL_checkfunction(L, 2);
for (i=1; i <= n; i++) { for (i=1; i <= n; i++) {
lua_pushvalue(L, 2); /* function */ lua_pushvalue(L, 2); /* function */
lua_pushinteger(L, i); /* 1st argument */ lua_pushinteger(L, i); /* 1st argument */
...@@ -38,7 +36,7 @@ static int foreachi (lua_State *L) { ...@@ -38,7 +36,7 @@ static int foreachi (lua_State *L) {
static int foreach (lua_State *L) { static int foreach (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanyfunction(L, 2); luaL_checkfunction(L, 2);
lua_pushnil(L); /* first key */ lua_pushnil(L); /* first key */
while (lua_next(L, 1)) { while (lua_next(L, 1)) {
lua_pushvalue(L, 2); /* function */ lua_pushvalue(L, 2); /* function */
...@@ -266,7 +264,7 @@ static int sort (lua_State *L) { ...@@ -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( concat, tconcat )
LROT_FUNCENTRY( foreach, foreach ) LROT_FUNCENTRY( foreach, foreach )
LROT_FUNCENTRY( foreachi, foreachi ) LROT_FUNCENTRY( foreachi, foreachi )
......
...@@ -5,37 +5,35 @@ ...@@ -5,37 +5,35 @@
*/ */
#include <string.h>
#define ltm_c #define ltm_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <string.h>
#include "lobject.h" #include "lobject.h"
#include "lstate.h" #include "lstate.h"
#include "lgc.h"
#include "lstring.h" #include "lstring.h"
#include "ltable.h" #include "ltable.h"
#include "ltm.h" #include "ltm.h"
#include "lrotable.h"
/* These must be correspond to the LUA_T* defines in lua.h */
const char *const luaT_typenames[] = { const char *const luaT_typenames[] = {
"nil", "boolean", "romtable", "lightfunction", "userdata", "number", "nil", "boolean", "lightfunction","number", // base type = 0, 1, 2, 3
"string", "table", "function", "userdata", "thread", "string", "table", "function", "userdata", "thread", // base type = 4, 5, 6, 7, 8
"proto", "upval" "proto", "upval"
}; };
void luaT_init (lua_State *L) { void luaT_init (lua_State *L) {
static const char *const luaT_eventname[] = { /* ORDER TM */ static const char *const luaT_eventname[] = { /* ORDER TM */
"__index", "__newindex", "__index", "__newindex",
"__gc", "__mode", "__eq", "__gc", "__mode", "__eq",
"__add", "__sub", "__mul", "__div", "__mod", "__add", "__sub", "__mul", "__div", "__mod",
"__pow", "__unm", "__len", "__lt", "__le", "__pow", "__unm", "__len", "__lt", "__le",
"__concat", "__call" "__concat", "__call",
"__metatable"
}; };
int i; int i;
for (i=0; i<TM_N; i++) { for (i=0; i<TM_N; i++) {
...@@ -50,22 +48,14 @@ void luaT_init (lua_State *L) { ...@@ -50,22 +48,14 @@ void luaT_init (lua_State *L) {
** tag methods ** tag methods
*/ */
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 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); lua_assert(event <= TM_EQ);
if (luaR_isrotable(events)) {
tm = luaH_getstr_ro(events, ename);
if (ttisnil(tm)) { /* no tag method? */ 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; return NULL;
} }
} else { else return tm;
tm = luaH_getstr(events, ename);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= cast_byte(1u<<event); /* cache this fact */
return NULL;
}
}
return tm;
} }
...@@ -73,21 +63,14 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { ...@@ -73,21 +63,14 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt; Table *mt;
switch (ttype(o)) { switch (ttype(o)) {
case LUA_TTABLE: case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
case LUA_TROTABLE: case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(o)); mt = hvalue(o)->metatable;
break; break;
case LUA_TUSERDATA: case LUA_TUSERDATA:
mt = uvalue(o)->metatable; mt = uvalue(o)->metatable;
break; break;
default: default:
mt = G(L)->mt[ttype(o)]; mt = G(L)->mt[ttnov(o)];
} }
if (!mt) return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
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]);
} }
...@@ -7,10 +7,6 @@ ...@@ -7,10 +7,6 @@
#ifndef ltm_h #ifndef ltm_h
#define ltm_h #define ltm_h
#include "lobject.h"
#include "lrotable.h"
/* /*
* WARNING: if you change the order of this enumeration, * WARNING: if you change the order of this enumeration,
* grep "ORDER TM" * grep "ORDER TM"
...@@ -33,13 +29,16 @@ typedef enum { ...@@ -33,13 +29,16 @@ typedef enum {
TM_LE, TM_LE,
TM_CONCAT, TM_CONCAT,
TM_CALL, TM_CALL,
TM_METATABLE,
TM_N /* number of elements in the enum */ TM_N /* number of elements in the enum */
} TMS; } TMS;
//#include "lobject.h"
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ #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) #define fasttm(l,et,e) gfasttm(G(l), et, e)
LUAI_DATA const char *const luaT_typenames[]; LUAI_DATA const char *const luaT_typenames[];
......
#include "llimits.h"
#include "lauxlib.h"
#include "lualib.h"
#define LUA_VERSION_51
#include "../lua-5.3/lua.c"
...@@ -8,13 +8,11 @@ ...@@ -8,13 +8,11 @@
#ifndef lua_h #ifndef lua_h
#define lua_h #define lua_h
#ifdef LUAC_CROSS_FILE #include <stdint.h>
#include "luac_cross.h"
#endif
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <ctype.h> #include <ctype.h>
#include <stdbool.h>
#include "luaconf.h" #include "luaconf.h"
...@@ -41,7 +39,8 @@ ...@@ -41,7 +39,8 @@
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
/* thread status; 0 is OK */ /* thread status */
#define LUA_OK 0
#define LUA_YIELD 1 #define LUA_YIELD 1
#define LUA_ERRRUN 2 #define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3 #define LUA_ERRSYNTAX 3
...@@ -72,18 +71,22 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); ...@@ -72,18 +71,22 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
** basic types ** basic types
*/ */
#define LUA_TNONE (-1) #define LUA_TNONE (-1)
#define LUA_TNIL 0 #define LUA_TNIL 0
#define LUA_TBOOLEAN 1 #define LUA_TBOOLEAN 1
#define LUA_TROTABLE 2 #define LUA_TLIGHTUSERDATA 2
#define LUA_TLIGHTFUNCTION 3 #define LUA_TNUMBER 3
#define LUA_TLIGHTUSERDATA 4 #define LUA_TSTRING 4
#define LUA_TNUMBER 5 #define LUA_TTABLE 5
#define LUA_TSTRING 6 #define LUA_TFUNCTION 6
#define LUA_TTABLE 7 #define LUA_TUSERDATA 7
#define LUA_TFUNCTION 8 #define LUA_TTHREAD 8
#define LUA_TUSERDATA 9
#define LUA_TTHREAD 10 #define LUA_TISROTABLE (1<<4)
#define LUA_TISLIGHTFUNC (1<<5)
#define LUA_TMASK 15
#define LUA_TROTABLE (LUA_TTABLE + LUA_TISROTABLE)
#define LUA_TLIGHTFUNCTION (LUA_TFUNCTION + LUA_TISLIGHTFUNC)
/* minimum Lua stack available to a C function */ /* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20 #define LUA_MINSTACK 20
...@@ -96,18 +99,14 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); ...@@ -96,18 +99,14 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
#include LUA_USER_H #include LUA_USER_H
#endif #endif
#if defined(LUA_OPTIMIZE_DEBUG) && LUA_OPTIMIZE_DEBUG == 0
#undef LUA_OPTIMIZE_DEBUG
#endif
/* type of numbers in Lua */ /* type of numbers in Lua */
typedef LUA_NUMBER lua_Number; typedef LUA_NUMBER lua_Number;
typedef LUA_FLOAT lua_Float;
/* type for integer functions */ /* type for integer functions */
typedef LUA_INTEGER lua_Integer; typedef LUA_INTEGER lua_Integer;
typedef LUAI_UINT32 lua_Unsigned;
/* /*
** state manipulation ** state manipulation
...@@ -122,6 +121,7 @@ LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); ...@@ -122,6 +121,7 @@ LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
/* /*
** basic stack manipulation ** basic stack manipulation
*/ */
LUA_API int (lua_absindex) (lua_State *L, int idx);
LUA_API int (lua_gettop) (lua_State *L); LUA_API int (lua_gettop) (lua_State *L);
LUA_API void (lua_settop) (lua_State *L, int idx); LUA_API void (lua_settop) (lua_State *L, int idx);
LUA_API void (lua_pushvalue) (lua_State *L, int idx); LUA_API void (lua_pushvalue) (lua_State *L, int idx);
...@@ -142,11 +142,14 @@ LUA_API int (lua_isstring) (lua_State *L, int idx); ...@@ -142,11 +142,14 @@ LUA_API int (lua_isstring) (lua_State *L, int idx);
LUA_API int (lua_iscfunction) (lua_State *L, int idx); LUA_API int (lua_iscfunction) (lua_State *L, int idx);
LUA_API int (lua_isuserdata) (lua_State *L, int idx); LUA_API int (lua_isuserdata) (lua_State *L, int idx);
LUA_API int (lua_type) (lua_State *L, int idx); LUA_API int (lua_type) (lua_State *L, int idx);
LUA_API int (lua_fulltype) (lua_State *L, int idx);
LUA_API const char *(lua_typename) (lua_State *L, int tp); LUA_API const char *(lua_typename) (lua_State *L, int tp);
LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); #define LUA_OPEQ 0
LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); #define LUA_OPLT 1
#define LUA_OPLE 2
LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
...@@ -173,18 +176,17 @@ LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); ...@@ -173,18 +176,17 @@ LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b); LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API void (lua_pushlightfunction) (lua_State *L, void *p);
LUA_API void (lua_pushrotable) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L); LUA_API int (lua_pushthread) (lua_State *L);
/* /*
** get functions (Lua -> stack) ** get functions (Lua -> stack)
*/ */
LUA_API void (lua_gettable) (lua_State *L, int idx); LUA_API int (lua_gettable) (lua_State *L, int idx);
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawget) (lua_State *L, int idx); LUA_API int (lua_rawget) (lua_State *L, int idx);
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); LUA_API int (lua_rawgeti) (lua_State *L, int idx, int n);
LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
LUA_API int (lua_getmetatable) (lua_State *L, int objindex); LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
...@@ -198,6 +200,7 @@ LUA_API void (lua_settable) (lua_State *L, int idx); ...@@ -198,6 +200,7 @@ LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawset) (lua_State *L, int idx); LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
LUA_API int (lua_setmetatable) (lua_State *L, int objindex); LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
LUA_API int (lua_setfenv) (lua_State *L, int idx); LUA_API int (lua_setfenv) (lua_State *L, int idx);
...@@ -210,8 +213,8 @@ LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); ...@@ -210,8 +213,8 @@ LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
const char *chunkname); const char *chunkname);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int stripping);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); LUA_API int (lua_stripdebug) (lua_State *L, int stripping);
/* /*
...@@ -271,10 +274,8 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); ...@@ -271,10 +274,8 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
#define lua_strlen(L,i) lua_objlen(L, (i)) #define lua_strlen(L,i) lua_objlen(L, (i))
#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_islightfunction(L,n) (lua_type(L, (n)) == LUA_TLIGHTFUNCTION)
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
#define lua_isrotable(L,n) (lua_type(L, (n)) == LUA_TROTABLE) #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) #define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
...@@ -289,14 +290,24 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); ...@@ -289,14 +290,24 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) #define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
#define lua_tounsigned(L,i) ((lua_Unsigned)lua_tointeger(L,i))
/* error codes from cross-compiler returned by lua_dump */
/* target integer is too small to hold a value */
#define LUA_ERR_CC_INTOVERFLOW 101
/* target lua_Number is integral but a constant is non-integer */
#define LUA_ERR_CC_NOTINTEGER 102
/* /*
** compatibility macros and functions ** compatibility macros and functions
*/ */
// BogdanM: modified for eLua interrupt support // BogdanM: modified for eLua interrupt support
//#define lua_open() luaL_newstate()
lua_State* lua_open(void); lua_State* lua_open(void);
lua_State* lua_getstate(void); lua_State* lua_getstate(void);
...@@ -372,24 +383,62 @@ struct lua_Debug { ...@@ -372,24 +383,62 @@ struct lua_Debug {
int i_ci; /* active function */ int i_ci; /* active function */
}; };
int lua_main(void);
void lua_input_string (const char *line, int len);
/* }====================================================================== */ /* }====================================================================== */
typedef struct __lua_load{ /* NodeMCU extensions to the standard API */
lua_State *L;
int firstline;
char *line;
int line_position;
size_t len;
int done;
const char *prmt;
}lua_Load;
int lua_main( int argc, char **argv ); typedef struct ROTable ROTable;
typedef const struct ROTable_entry ROTable_entry;
#ifndef LUA_CROSS_COMPILER LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
void lua_handle_input (bool force); LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, ROTable_entry *e, ROTable *mt);
LUA_API int (lua_pushstringsarray) (lua_State *L, int opt);
LUA_API int (lua_freeheap) (void);
LUA_API void (lua_getlfsconfig) (lua_State *L, int *);
LUA_API int (lua_pushlfsindex) (lua_State *L);
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
#define EGC_ON_MEM_LIMIT 2 // run EGC when an upper memory limit is hit
#define EGC_ALWAYS 4 // always run EGC before an allocation
#ifdef LUA_USE_ESP
#define LUA_QUEUE_APP 0
#define LUA_QUEUE_UART 1
/**DEBUG**/extern void dbg_printf(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
#define luaN_freearray(L,b,l) luaM_freearray(L,b,l,sizeof(*b))
LUA_API void (lua_setegcmode) (lua_State *L, int mode, int limit);
LUA_API void (lua_getegcinfo) (lua_State *L, int *totals);
#else
#define ICACHE_RODATA_ATTR
#define dbg_printf printf
#endif
#ifdef DEVELOPMENT_USE_GDB
LUALIB_API void (lua_debugbreak)(void);
#else
#define lua_debugbreak() (void)(0)
#endif #endif
// EGC operations modes
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
#define EGC_ON_MEM_LIMIT 2 // run EGC when an upper memory limit is hit
#define EGC_ALWAYS 4 // always run EGC before an allocation
void legc_set_mode(lua_State *L, int mode, int limit);
/****************************************************************************** /******************************************************************************
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. * Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
* *
......
...@@ -155,6 +155,11 @@ ...@@ -155,6 +155,11 @@
#define LUA_EXECDIR "!" #define LUA_EXECDIR "!"
#define LUA_IGMARK "-" #define LUA_IGMARK "-"
#ifdef CONFIG_LUA_NUMBER_INTEGRAL
# define LUA_NUMBER_INTEGRAL
#else
# define LUA_PACK_TVALUES
#endif
/* /*
@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
...@@ -265,16 +270,6 @@ ...@@ -265,16 +270,6 @@
#endif #endif
/*
@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
** CHANGE them if you want different prompts. (You can also change the
** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
*/
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
/* /*
@@ LUA_PROGNAME is the default name for the stand-alone Lua program. @@ LUA_PROGNAME is the default name for the stand-alone Lua program.
** CHANGE it if your stand-alone interpreter has a different name and ** CHANGE it if your stand-alone interpreter has a different name and
...@@ -299,54 +294,34 @@ ...@@ -299,54 +294,34 @@
** CHANGE them if you want to improve this functionality (e.g., by using ** CHANGE them if you want to improve this functionality (e.g., by using
** GNU readline and history facilities). ** GNU readline and history facilities).
*/ */
#if defined(LUA_USE_STDIO)
#if defined(LUA_CROSS_COMPILER) && defined(LUA_USE_READLINE)
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
#define lua_saveline(L,idx) \
if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
add_history(lua_tostring(L, idx)); /* add it to history */
#define lua_freeline(L,b) ((void)L, free(b))
#else // #if defined(LUA_CROSS_COMPILER) && defined(LUA_USE_READLINE)
#define lua_readline(L,b,p) \
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
#define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_freeline(L,b) { (void)L; (void)b; }
#endif // #if defined(LUA_USE_READLINE)
#else // #if defined(LUA_USE_STDIO)
#define lua_readline(L,b,p) (readline4lua(p, b, LUA_MAXINPUT)) #define lua_readline(L,b,p) (readline4lua(p, b, LUA_MAXINPUT))
#define lua_saveline(L,idx) { (void)L; (void)idx; } #define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_freeline(L,b) { (void)L; (void)b; } #define lua_freeline(L,b) { (void)L; (void)b; }
extern int readline4lua(const char *prompt, char *buffer, int length); extern int readline4lua(const char *prompt, char *buffer, int length);
#endif // #if defined(LUA_USE_STDIO)
/* /*
@@ luai_writestring/luai_writeline define how 'print' prints its results. @@ lua_writestring/lua_writeline define how 'print' prints its results.
** They are only used in libraries and the stand-alone program. (The #if ** They are only used in libraries and the stand-alone program. (The #if
** avoids including 'stdio.h' everywhere.) ** avoids including 'stdio.h' everywhere.)
*/ */
#if !defined(LUA_USE_STDIO) #ifdef LUA_USE_ESP
#define luai_writestring(s, l) fwrite(s, 1, l, stdout) void output_redirect(const char *str, size_t l);
#define luai_writeline() puts("") #define lua_writestring(s,l) output_redirect((s),(l))
#endif // defined(LUA_USE_STDIO) #else
#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#endif
#define luai_writeline() lua_writestring("\n",1)
/* /*
@@ luai_writestringerror defines how to print error messages. @@ lua_writestringerror defines how to print error messages.
** (A format string with one argument is enough for Lua...) ** (A format string with one argument is enough for Lua...)
*/ */
#if !defined(LUA_USE_STDIO) #ifdef LUA_USE_ESP
#define luai_writestringerror(s,p) printf((s), (p)) #define lua_writestringerror(s,p) dbg_printf((s), (p))
#endif // defined(LUA_USE_STDIO) #else
#define lua_writestringerror(s,p) fprintf(stderr, (s), (p))
#endif
/* }================================================================== */
/* /*
...@@ -586,6 +561,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length); ...@@ -586,6 +561,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
#define LUA_NUMBER_DOUBLE #define LUA_NUMBER_DOUBLE
#define LUA_NUMBER double #define LUA_NUMBER double
#endif #endif
#define LUA_FLOAT double
/* /*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' @@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
...@@ -897,4 +873,6 @@ union luai_Cast { double l_d; long l_l; }; ...@@ -897,4 +873,6 @@ union luai_Cast { double l_d; long l_l; };
#error "Pipes not supported NodeMCU firmware" #error "Pipes not supported NodeMCU firmware"
#endif #endif
#define LUA_DEBUG_HOOK lua_debugbreak
#endif #endif
...@@ -41,7 +41,7 @@ LUALIB_API int (luaopen_package) (lua_State *L); ...@@ -41,7 +41,7 @@ LUALIB_API int (luaopen_package) (lua_State *L);
/* open all previous libraries */ /* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L); LUALIB_API void (luaL_openlibs) (lua_State *L);
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define lundump_c #define lundump_c
#define LUA_CORE #define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h" #include "lua.h"
#include <string.h> #include <string.h>
...@@ -164,16 +163,9 @@ static TString* LoadString(LoadState* S) ...@@ -164,16 +163,9 @@ static TString* LoadString(LoadState* S)
return NULL; return NULL;
else else
{ {
char* s; char* s = luaZ_openspace(S->L,S->b,size);
if (!luaZ_direct_mode(S->Z)) { LoadBlock(S,s,size);
s = luaZ_openspace(S->L,S->b,size); return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */
LoadBlock(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */
} else {
s = (char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,size);
return luaS_newlstr(S->L,s,size-1);
}
} }
} }
...@@ -181,13 +173,8 @@ static void LoadCode(LoadState* S, Proto* f) ...@@ -181,13 +173,8 @@ static void LoadCode(LoadState* S, Proto* f)
{ {
int n=LoadInt(S); int n=LoadInt(S);
Align4(S); Align4(S);
if (!luaZ_direct_mode(S->Z)) { f->code=luaM_newvector(S->L,n,Instruction);
f->code=luaM_newvector(S->L,n,Instruction); LoadVector(S,f->code,n,sizeof(Instruction));
LoadVector(S,f->code,n,sizeof(Instruction));
} else {
f->code=(Instruction*)luaZ_get_crt_address(S->Z);
LoadVector(S,NULL,n,sizeof(Instruction));
}
f->sizecode=n; f->sizecode=n;
} }
...@@ -236,28 +223,12 @@ static void LoadDebug(LoadState* S, Proto* f) ...@@ -236,28 +223,12 @@ static void LoadDebug(LoadState* S, Proto* f)
n=LoadInt(S); n=LoadInt(S);
Align4(S); Align4(S);
#ifdef LUA_OPTIMIZE_DEBUG
if(n) { if(n) {
if (!luaZ_direct_mode(S->Z)) { f->packedlineinfo=luaM_newvector(S->L,n,unsigned char);
f->packedlineinfo=luaM_newvector(S->L,n,unsigned char); LoadBlock(S,f->packedlineinfo,n);
LoadBlock(S,f->packedlineinfo,n);
} else {
f->packedlineinfo=(unsigned char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,n);
}
} else { } else {
f->packedlineinfo=NULL; f->packedlineinfo=NULL;
} }
#else
if (!luaZ_direct_mode(S->Z)) {
f->lineinfo=luaM_newvector(S->L,n,int);
LoadVector(S,f->lineinfo,n,sizeof(int));
} else {
f->lineinfo=(int*)luaZ_get_crt_address(S->Z);
LoadVector(S,NULL,n,sizeof(int));
}
f->sizelineinfo=n;
#endif
n=LoadInt(S); n=LoadInt(S);
f->locvars=luaM_newvector(S->L,n,LocVar); f->locvars=luaM_newvector(S->L,n,LocVar);
f->sizelocvars=n; f->sizelocvars=n;
...@@ -280,7 +251,6 @@ static Proto* LoadFunction(LoadState* S, TString* p) ...@@ -280,7 +251,6 @@ static Proto* LoadFunction(LoadState* S, TString* p)
Proto* f; Proto* f;
if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
f=luaF_newproto(S->L); f=luaF_newproto(S->L);
if (luaZ_direct_mode(S->Z)) l_setbit((f)->marked, READONLYBIT);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
f->source=LoadString(S); if (f->source==NULL) f->source=p; f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S); f->linedefined=LoadInt(S);
......
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