mirror of
https://github.com/lua/lua.git
synced 2025-02-04 06:13:04 +08:00
Merge branch 'master' into nextversion
This commit is contained in:
commit
c815c2f0eb
4
lapi.c
4
lapi.c
@ -417,9 +417,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
|
|||||||
o = index2value(L, idx); /* previous call may reallocate the stack */
|
o = index2value(L, idx); /* previous call may reallocate the stack */
|
||||||
}
|
}
|
||||||
if (len != NULL)
|
if (len != NULL)
|
||||||
*len = vslen(o);
|
*len = tsslen(tsvalue(o));
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return svalue(o);
|
return getstr(tsvalue(o));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
28
ldebug.c
28
ldebug.c
@ -426,7 +426,7 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
|
|||||||
*/
|
*/
|
||||||
static void kname (const Proto *p, int c, const char **name) {
|
static void kname (const Proto *p, int c, const char **name) {
|
||||||
TValue *kvalue = &p->k[c];
|
TValue *kvalue = &p->k[c];
|
||||||
*name = (ttisstring(kvalue)) ? svalue(kvalue) : "?";
|
*name = (ttisstring(kvalue)) ? getstr(tsvalue(kvalue)) : "?";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -569,7 +569,7 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
|
|||||||
int b = (op == OP_LOADK) ? GETARG_Bx(i)
|
int b = (op == OP_LOADK) ? GETARG_Bx(i)
|
||||||
: GETARG_Ax(p->code[pc + 1]);
|
: GETARG_Ax(p->code[pc + 1]);
|
||||||
if (ttisstring(&p->k[b])) {
|
if (ttisstring(&p->k[b])) {
|
||||||
*name = svalue(&p->k[b]);
|
*name = getstr(tsvalue(&p->k[b]));
|
||||||
return "constant";
|
return "constant";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -627,7 +627,7 @@ static const char *funcnamefromcode (lua_State *L, const Proto *p,
|
|||||||
default:
|
default:
|
||||||
return NULL; /* cannot find a reasonable name */
|
return NULL; /* cannot find a reasonable name */
|
||||||
}
|
}
|
||||||
*name = getstr(G(L)->tmname[tm]) + 2;
|
*name = getshrstr(G(L)->tmname[tm]) + 2;
|
||||||
return "metamethod";
|
return "metamethod";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,6 +865,28 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Traces Lua calls. If code is running the first instruction of a function,
|
||||||
|
** and function is not vararg, and it is not coming from an yield,
|
||||||
|
** calls 'luaD_hookcall'. (Vararg functions will call 'luaD_hookcall'
|
||||||
|
** after adjusting its variable arguments; otherwise, they could call
|
||||||
|
** a line/count hook before the call hook. Functions coming from
|
||||||
|
** an yield already called 'luaD_hookcall' before yielding.)
|
||||||
|
*/
|
||||||
|
int luaG_tracecall (lua_State *L) {
|
||||||
|
CallInfo *ci = L->ci;
|
||||||
|
Proto *p = ci_func(ci)->p;
|
||||||
|
ci->u.l.trap = 1; /* ensure hooks will be checked */
|
||||||
|
if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */
|
||||||
|
if (p->is_vararg)
|
||||||
|
return 0; /* hooks will start at VARARGPREP instruction */
|
||||||
|
else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yieded? */
|
||||||
|
luaD_hookcall(L, ci); /* check 'call' hook */
|
||||||
|
}
|
||||||
|
return 1; /* keep 'trap' on */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Traces the execution of a Lua function. Called before the execution
|
** Traces the execution of a Lua function. Called before the execution
|
||||||
** of each opcode, when debug is on. 'L->oldpc' stores the last
|
** of each opcode, when debug is on. 'L->oldpc' stores the last
|
||||||
|
1
ldebug.h
1
ldebug.h
@ -58,6 +58,7 @@ LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
|
|||||||
TString *src, int line);
|
TString *src, int line);
|
||||||
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
|
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
|
||||||
LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc);
|
LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc);
|
||||||
|
LUAI_FUNC int luaG_tracecall (lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
16
lgc.c
16
lgc.c
@ -533,10 +533,12 @@ static void traversestrongtable (global_State *g, Table *h) {
|
|||||||
static void traversetable (global_State *g, Table *h) {
|
static void traversetable (global_State *g, Table *h) {
|
||||||
const char *weakkey, *weakvalue;
|
const char *weakkey, *weakvalue;
|
||||||
const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
|
const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
|
||||||
|
TString *smode;
|
||||||
markobjectN(g, h->metatable);
|
markobjectN(g, h->metatable);
|
||||||
if (mode && ttisstring(mode) && /* is there a weak mode? */
|
if (mode && ttisshrstring(mode) && /* is there a weak mode? */
|
||||||
(cast_void(weakkey = strchr(svalue(mode), 'k')),
|
(cast_void(smode = tsvalue(mode)),
|
||||||
cast_void(weakvalue = strchr(svalue(mode), 'v')),
|
cast_void(weakkey = strchr(getshrstr(smode), 'k')),
|
||||||
|
cast_void(weakvalue = strchr(getshrstr(smode), 'v')),
|
||||||
(weakkey || weakvalue))) { /* is really weak? */
|
(weakkey || weakvalue))) { /* is really weak? */
|
||||||
if (!weakkey) /* strong keys? */
|
if (!weakkey) /* strong keys? */
|
||||||
traverseweakvalue(g, h);
|
traverseweakvalue(g, h);
|
||||||
@ -624,7 +626,9 @@ static void traversethread (global_State *g, lua_State *th) {
|
|||||||
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
|
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
|
||||||
markobject(g, uv); /* open upvalues cannot be collected */
|
markobject(g, uv); /* open upvalues cannot be collected */
|
||||||
if (g->gcstate == GCSatomic) { /* final traversal? */
|
if (g->gcstate == GCSatomic) { /* final traversal? */
|
||||||
for (; o < th->stack_last.p + EXTRA_STACK; o++)
|
if (!g->gcemergency)
|
||||||
|
luaD_shrinkstack(th); /* do not change stack in emergency cycle */
|
||||||
|
for (o = th->top.p; o < th->stack_last.p + EXTRA_STACK; o++)
|
||||||
setnilvalue(s2v(o)); /* clear dead stack slice */
|
setnilvalue(s2v(o)); /* clear dead stack slice */
|
||||||
/* 'remarkupvals' may have removed thread from 'twups' list */
|
/* 'remarkupvals' may have removed thread from 'twups' list */
|
||||||
if (!isintwups(th) && th->openupval != NULL) {
|
if (!isintwups(th) && th->openupval != NULL) {
|
||||||
@ -632,8 +636,6 @@ static void traversethread (global_State *g, lua_State *th) {
|
|||||||
g->twups = th;
|
g->twups = th;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!g->gcemergency)
|
|
||||||
luaD_shrinkstack(th); /* do not change stack in emergency cycle */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1644,6 +1646,8 @@ static void fullinc (lua_State *L, global_State *g) {
|
|||||||
entersweep(L); /* sweep everything to turn them back to white */
|
entersweep(L); /* sweep everything to turn them back to white */
|
||||||
/* finish any pending sweep phase to start a new cycle */
|
/* finish any pending sweep phase to start a new cycle */
|
||||||
luaC_runtilstate(L, bitmask(GCSpause));
|
luaC_runtilstate(L, bitmask(GCSpause));
|
||||||
|
luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
|
||||||
|
g->gcstate = GCSenteratomic; /* go straight to atomic phase ??? */
|
||||||
luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
|
luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
|
||||||
/* 'marked' must be correct after a full GC cycle */
|
/* 'marked' must be correct after a full GC cycle */
|
||||||
lua_assert(g->marked == gettotalobjs(g));
|
lua_assert(g->marked == gettotalobjs(g));
|
||||||
|
@ -542,7 +542,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
|||||||
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
|
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
|
||||||
clearbuff(&buff); /* empty buffer into the stack */
|
clearbuff(&buff); /* empty buffer into the stack */
|
||||||
lua_assert(buff.pushed == 1);
|
lua_assert(buff.pushed == 1);
|
||||||
return svalue(s2v(L->top.p - 1));
|
return getstr(tsvalue(s2v(L->top.p - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
16
lobject.h
16
lobject.h
@ -386,7 +386,7 @@ typedef struct GCObject {
|
|||||||
typedef struct TString {
|
typedef struct TString {
|
||||||
CommonHeader;
|
CommonHeader;
|
||||||
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
|
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
|
||||||
lu_byte shrlen; /* length for short strings */
|
lu_byte shrlen; /* length for short strings, 0xFF for long strings */
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
union {
|
union {
|
||||||
size_t lnglen; /* length for long strings */
|
size_t lnglen; /* length for long strings */
|
||||||
@ -398,19 +398,17 @@ typedef struct TString {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Get the actual string (array of bytes) from a 'TString'.
|
** Get the actual string (array of bytes) from a 'TString'. (Generic
|
||||||
|
** version and specialized versions for long and short strings.)
|
||||||
*/
|
*/
|
||||||
#define getstr(ts) ((ts)->contents)
|
#define getstr(ts) ((ts)->contents)
|
||||||
|
#define getlngstr(ts) check_exp((ts)->shrlen == 0xFF, (ts)->contents)
|
||||||
|
#define getshrstr(ts) check_exp((ts)->shrlen != 0xFF, (ts)->contents)
|
||||||
|
|
||||||
|
|
||||||
/* get the actual string (array of bytes) from a Lua value */
|
|
||||||
#define svalue(o) getstr(tsvalue(o))
|
|
||||||
|
|
||||||
/* get string length from 'TString *s' */
|
/* get string length from 'TString *s' */
|
||||||
#define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen)
|
#define tsslen(s) \
|
||||||
|
((s)->shrlen != 0xFF ? (s)->shrlen : (s)->u.lnglen)
|
||||||
/* get string length from 'TValue *o' */
|
|
||||||
#define vslen(o) tsslen(tsvalue(o))
|
|
||||||
|
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
|
|
||||||
|
12
lparser.c
12
lparser.c
@ -1030,10 +1030,11 @@ static int explist (LexState *ls, expdesc *v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void funcargs (LexState *ls, expdesc *f, int line) {
|
static void funcargs (LexState *ls, expdesc *f) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
expdesc args;
|
expdesc args;
|
||||||
int base, nparams;
|
int base, nparams;
|
||||||
|
int line = ls->linenumber;
|
||||||
switch (ls->t.token) {
|
switch (ls->t.token) {
|
||||||
case '(': { /* funcargs -> '(' [ explist ] ')' */
|
case '(': { /* funcargs -> '(' [ explist ] ')' */
|
||||||
luaX_next(ls);
|
luaX_next(ls);
|
||||||
@ -1071,8 +1072,8 @@ static void funcargs (LexState *ls, expdesc *f, int line) {
|
|||||||
}
|
}
|
||||||
init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
|
init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
|
||||||
luaK_fixline(fs, line);
|
luaK_fixline(fs, line);
|
||||||
fs->freereg = base+1; /* call remove function and arguments and leaves
|
fs->freereg = base+1; /* call removes function and arguments and leaves
|
||||||
(unless changed) one result */
|
one result (unless changed later) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1111,7 +1112,6 @@ static void suffixedexp (LexState *ls, expdesc *v) {
|
|||||||
/* suffixedexp ->
|
/* suffixedexp ->
|
||||||
primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
|
primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
int line = ls->linenumber;
|
|
||||||
primaryexp(ls, v);
|
primaryexp(ls, v);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (ls->t.token) {
|
switch (ls->t.token) {
|
||||||
@ -1131,12 +1131,12 @@ static void suffixedexp (LexState *ls, expdesc *v) {
|
|||||||
luaX_next(ls);
|
luaX_next(ls);
|
||||||
codename(ls, &key);
|
codename(ls, &key);
|
||||||
luaK_self(fs, v, &key);
|
luaK_self(fs, v, &key);
|
||||||
funcargs(ls, v, line);
|
funcargs(ls, v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '(': case TK_STRING: case '{': { /* funcargs */
|
case '(': case TK_STRING: case '{': { /* funcargs */
|
||||||
luaK_exp2nextreg(fs, v);
|
luaK_exp2nextreg(fs, v);
|
||||||
funcargs(ls, v, line);
|
funcargs(ls, v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: return;
|
default: return;
|
||||||
|
2
lstate.c
2
lstate.c
@ -396,7 +396,7 @@ void luaE_warning (lua_State *L, const char *msg, int tocont) {
|
|||||||
void luaE_warnerror (lua_State *L, const char *where) {
|
void luaE_warnerror (lua_State *L, const char *where) {
|
||||||
TValue *errobj = s2v(L->top.p - 1); /* error object */
|
TValue *errobj = s2v(L->top.p - 1); /* error object */
|
||||||
const char *msg = (ttisstring(errobj))
|
const char *msg = (ttisstring(errobj))
|
||||||
? svalue(errobj)
|
? getstr(tsvalue(errobj))
|
||||||
: "error object is not a string";
|
: "error object is not a string";
|
||||||
/* produce warning "error in %s (%s)" (where, msg) */
|
/* produce warning "error in %s (%s)" (where, msg) */
|
||||||
luaE_warning(L, "error in ", 1);
|
luaE_warning(L, "error in ", 1);
|
||||||
|
2
lstate.h
2
lstate.h
@ -182,7 +182,7 @@ struct CallInfo {
|
|||||||
union {
|
union {
|
||||||
struct { /* only for Lua functions */
|
struct { /* only for Lua functions */
|
||||||
const Instruction *savedpc;
|
const Instruction *savedpc;
|
||||||
volatile l_signalT trap;
|
volatile l_signalT trap; /* function is tracing lines/counts */
|
||||||
int nextraargs; /* # of extra arguments in vararg functions */
|
int nextraargs; /* # of extra arguments in vararg functions */
|
||||||
} l;
|
} l;
|
||||||
struct { /* only for C functions */
|
struct { /* only for C functions */
|
||||||
|
11
lstring.c
11
lstring.c
@ -36,7 +36,7 @@ int luaS_eqlngstr (TString *a, TString *b) {
|
|||||||
lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR);
|
lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR);
|
||||||
return (a == b) || /* same instance or... */
|
return (a == b) || /* same instance or... */
|
||||||
((len == b->u.lnglen) && /* equal length and ... */
|
((len == b->u.lnglen) && /* equal length and ... */
|
||||||
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
|
(memcmp(getlngstr(a), getlngstr(b), len) == 0)); /* equal contents */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ unsigned int luaS_hashlongstr (TString *ts) {
|
|||||||
lua_assert(ts->tt == LUA_VLNGSTR);
|
lua_assert(ts->tt == LUA_VLNGSTR);
|
||||||
if (ts->extra == 0) { /* no hash? */
|
if (ts->extra == 0) { /* no hash? */
|
||||||
size_t len = ts->u.lnglen;
|
size_t len = ts->u.lnglen;
|
||||||
ts->hash = luaS_hash(getstr(ts), len, ts->hash);
|
ts->hash = luaS_hash(getlngstr(ts), len, ts->hash);
|
||||||
ts->extra = 1; /* now it has its hash */
|
ts->extra = 1; /* now it has its hash */
|
||||||
}
|
}
|
||||||
return ts->hash;
|
return ts->hash;
|
||||||
@ -157,6 +157,7 @@ static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) {
|
|||||||
TString *luaS_createlngstrobj (lua_State *L, size_t l) {
|
TString *luaS_createlngstrobj (lua_State *L, size_t l) {
|
||||||
TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed);
|
TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed);
|
||||||
ts->u.lnglen = l;
|
ts->u.lnglen = l;
|
||||||
|
ts->shrlen = 0xFF; /* signals that it is a long string */
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +194,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
|
|||||||
TString **list = &tb->hash[lmod(h, tb->size)];
|
TString **list = &tb->hash[lmod(h, tb->size)];
|
||||||
lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */
|
lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */
|
||||||
for (ts = *list; ts != NULL; ts = ts->u.hnext) {
|
for (ts = *list; ts != NULL; ts = ts->u.hnext) {
|
||||||
if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
|
if (l == ts->shrlen && (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) {
|
||||||
/* found! */
|
/* found! */
|
||||||
if (isdead(g, ts)) /* dead (but not collected yet)? */
|
if (isdead(g, ts)) /* dead (but not collected yet)? */
|
||||||
changewhite(ts); /* resurrect it */
|
changewhite(ts); /* resurrect it */
|
||||||
@ -206,7 +207,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
|
|||||||
list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */
|
list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */
|
||||||
}
|
}
|
||||||
ts = createstrobj(L, l, LUA_VSHRSTR, h);
|
ts = createstrobj(L, l, LUA_VSHRSTR, h);
|
||||||
memcpy(getstr(ts), str, l * sizeof(char));
|
memcpy(getshrstr(ts), str, l * sizeof(char));
|
||||||
ts->shrlen = cast_byte(l);
|
ts->shrlen = cast_byte(l);
|
||||||
ts->u.hnext = *list;
|
ts->u.hnext = *list;
|
||||||
*list = ts;
|
*list = ts;
|
||||||
@ -226,7 +227,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
|||||||
if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char)))
|
if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char)))
|
||||||
luaM_toobig(L);
|
luaM_toobig(L);
|
||||||
ts = luaS_createlngstrobj(L, l);
|
ts = luaS_createlngstrobj(L, l);
|
||||||
memcpy(getstr(ts), str, l * sizeof(char));
|
memcpy(getlngstr(ts), str, l * sizeof(char));
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ static TString *loadStringN (LoadState *S, Proto *p) {
|
|||||||
ts = luaS_createlngstrobj(L, size); /* create string */
|
ts = luaS_createlngstrobj(L, size); /* create string */
|
||||||
setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */
|
setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
loadVector(S, getstr(ts), size); /* load directly in final place */
|
loadVector(S, getlngstr(ts), size); /* load directly in final place */
|
||||||
L->top.p--; /* pop string */
|
L->top.p--; /* pop string */
|
||||||
}
|
}
|
||||||
luaC_objbarrier(L, p, ts);
|
luaC_objbarrier(L, p, ts);
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
/*
|
/*
|
||||||
** Encode major-minor version in one byte, one nibble for each
|
** Encode major-minor version in one byte, one nibble for each
|
||||||
*/
|
*/
|
||||||
#define MYINT(s) (s[0]-'0') /* assume one-digit numerals */
|
#define LUAC_VERSION (LUA_VERSION_MAJOR_N*16+LUA_VERSION_MINOR_N)
|
||||||
#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR))
|
|
||||||
|
|
||||||
#define LUAC_FORMAT 0 /* this is the official format */
|
#define LUAC_FORMAT 0 /* this is the official format */
|
||||||
|
|
||||||
|
30
lvm.c
30
lvm.c
@ -91,8 +91,10 @@ static int l_strton (const TValue *obj, TValue *result) {
|
|||||||
lua_assert(obj != result);
|
lua_assert(obj != result);
|
||||||
if (!cvt2num(obj)) /* is object not a string? */
|
if (!cvt2num(obj)) /* is object not a string? */
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else {
|
||||||
return (luaO_str2num(svalue(obj), result) == vslen(obj) + 1);
|
TString *st = tsvalue(obj);
|
||||||
|
return (luaO_str2num(getstr(st), result) == tsslen(st) + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -627,8 +629,9 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
|||||||
static void copy2buff (StkId top, int n, char *buff) {
|
static void copy2buff (StkId top, int n, char *buff) {
|
||||||
size_t tl = 0; /* size already copied */
|
size_t tl = 0; /* size already copied */
|
||||||
do {
|
do {
|
||||||
size_t l = vslen(s2v(top - n)); /* length of string being copied */
|
TString *st = tsvalue(s2v(top - n));
|
||||||
memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char));
|
size_t l = tsslen(st); /* length of string being copied */
|
||||||
|
memcpy(buff + tl, getstr(st), l * sizeof(char));
|
||||||
tl += l;
|
tl += l;
|
||||||
} while (--n > 0);
|
} while (--n > 0);
|
||||||
}
|
}
|
||||||
@ -654,11 +657,11 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* at least two non-empty string values; get as many as possible */
|
/* at least two non-empty string values; get as many as possible */
|
||||||
size_t tl = vslen(s2v(top - 1));
|
size_t tl = tsslen(tsvalue(s2v(top - 1)));
|
||||||
TString *ts;
|
TString *ts;
|
||||||
/* collect total length and number of strings */
|
/* collect total length and number of strings */
|
||||||
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
||||||
size_t l = vslen(s2v(top - n - 1));
|
size_t l = tsslen(tsvalue(s2v(top - n - 1)));
|
||||||
if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
|
if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
|
||||||
L->top.p = top - total; /* pop strings to avoid wasting stack */
|
L->top.p = top - total; /* pop strings to avoid wasting stack */
|
||||||
luaG_runerror(L, "string length overflow");
|
luaG_runerror(L, "string length overflow");
|
||||||
@ -672,7 +675,7 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
}
|
}
|
||||||
else { /* long string; copy strings directly to final result */
|
else { /* long string; copy strings directly to final result */
|
||||||
ts = luaS_createlngstrobj(L, tl);
|
ts = luaS_createlngstrobj(L, tl);
|
||||||
copy2buff(top, n, getstr(ts));
|
copy2buff(top, n, getlngstr(ts));
|
||||||
}
|
}
|
||||||
setsvalue2s(L, top - n, ts); /* create result */
|
setsvalue2s(L, top - n, ts); /* create result */
|
||||||
}
|
}
|
||||||
@ -1158,18 +1161,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
startfunc:
|
startfunc:
|
||||||
trap = L->hookmask;
|
trap = L->hookmask;
|
||||||
returning: /* trap already set */
|
returning: /* trap already set */
|
||||||
cl = clLvalue(s2v(ci->func.p));
|
cl = ci_func(ci);
|
||||||
k = cl->p->k;
|
k = cl->p->k;
|
||||||
pc = ci->u.l.savedpc;
|
pc = ci->u.l.savedpc;
|
||||||
if (l_unlikely(trap)) {
|
if (l_unlikely(trap))
|
||||||
if (pc == cl->p->code) { /* first instruction (not resuming)? */
|
trap = luaG_tracecall(L);
|
||||||
if (cl->p->is_vararg)
|
|
||||||
trap = 0; /* hooks will start after VARARGPREP instruction */
|
|
||||||
else /* check 'call' hook */
|
|
||||||
luaD_hookcall(L, ci);
|
|
||||||
}
|
|
||||||
ci->u.l.trap = 1; /* assume trap is on, for now */
|
|
||||||
}
|
|
||||||
base = ci->func.p + 1;
|
base = ci->func.p + 1;
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -9033,6 +9033,10 @@ Lua does not consult any environment variables.
|
|||||||
In particular,
|
In particular,
|
||||||
the values of @Lid{package.path} and @Lid{package.cpath}
|
the values of @Lid{package.path} and @Lid{package.cpath}
|
||||||
are set with the default paths defined in @id{luaconf.h}.
|
are set with the default paths defined in @id{luaconf.h}.
|
||||||
|
To signal to the libraries that this option is on,
|
||||||
|
the stand-alone interpreter sets the field
|
||||||
|
@idx{"LUA_NOENV"} in the registry to a true value.
|
||||||
|
Other libraries may consult this field for the same purpose.
|
||||||
|
|
||||||
The options @T{-e}, @T{-l}, and @T{-W} are handled in
|
The options @T{-e}, @T{-l}, and @T{-W} are handled in
|
||||||
the order they appear.
|
the order they appear.
|
||||||
|
@ -342,7 +342,7 @@ do -- another bug (in 5.4.0)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- another bug (since 5.2)
|
if not _port then -- another bug (since 5.2)
|
||||||
-- corrupted binary dump: list of upvalue names is larger than number
|
-- corrupted binary dump: list of upvalue names is larger than number
|
||||||
-- of upvalues, overflowing the array of upvalues.
|
-- of upvalues, overflowing the array of upvalues.
|
||||||
local code =
|
local code =
|
||||||
|
@ -345,7 +345,7 @@ function f(a,b)
|
|||||||
local _, y = debug.getlocal(1, 2)
|
local _, y = debug.getlocal(1, 2)
|
||||||
assert(x == a and y == b)
|
assert(x == a and y == b)
|
||||||
assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
|
assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
|
||||||
assert(debug.setlocal(2, 4, "ma<EFBFBD><EFBFBD>") == "B")
|
assert(debug.setlocal(2, 4, "manga") == "B")
|
||||||
x = debug.getinfo(2)
|
x = debug.getinfo(2)
|
||||||
assert(x.func == g and x.what == "Lua" and x.name == 'g' and
|
assert(x.func == g and x.what == "Lua" and x.name == 'g' and
|
||||||
x.nups == 2 and string.find(x.source, "^@.*db%.lua$"))
|
x.nups == 2 and string.find(x.source, "^@.*db%.lua$"))
|
||||||
@ -373,9 +373,9 @@ function g (...)
|
|||||||
local arg = {...}
|
local arg = {...}
|
||||||
do local a,b,c; a=math.sin(40); end
|
do local a,b,c; a=math.sin(40); end
|
||||||
local feijao
|
local feijao
|
||||||
local AAAA,B = "xuxu", "mam<EFBFBD>o"
|
local AAAA,B = "xuxu", "abacate"
|
||||||
f(AAAA,B)
|
f(AAAA,B)
|
||||||
assert(AAAA == "pera" and B == "ma<EFBFBD><EFBFBD>")
|
assert(AAAA == "pera" and B == "manga")
|
||||||
do
|
do
|
||||||
local B = 13
|
local B = 13
|
||||||
local x,y = debug.getlocal(1,5)
|
local x,y = debug.getlocal(1,5)
|
||||||
|
@ -392,19 +392,19 @@ lineerror("a\n=\n-\n\nprint\n;", 3)
|
|||||||
|
|
||||||
lineerror([[
|
lineerror([[
|
||||||
a
|
a
|
||||||
(
|
( -- <<
|
||||||
23)
|
23)
|
||||||
]], 1)
|
]], 2)
|
||||||
|
|
||||||
lineerror([[
|
lineerror([[
|
||||||
local a = {x = 13}
|
local a = {x = 13}
|
||||||
a
|
a
|
||||||
.
|
.
|
||||||
x
|
x
|
||||||
(
|
( -- <<
|
||||||
23
|
23
|
||||||
)
|
)
|
||||||
]], 2)
|
]], 5)
|
||||||
|
|
||||||
lineerror([[
|
lineerror([[
|
||||||
local a = {x = 13}
|
local a = {x = 13}
|
||||||
|
@ -92,8 +92,8 @@ assert(io.output():seek("end") == string.len("alo joao"))
|
|||||||
|
|
||||||
assert(io.output():seek("set") == 0)
|
assert(io.output():seek("set") == 0)
|
||||||
|
|
||||||
assert(io.write('"<EFBFBD>lo"', "{a}\n", "second line\n", "third line \n"))
|
assert(io.write('"alo"', "{a}\n", "second line\n", "third line \n"))
|
||||||
assert(io.write('<EFBFBD>fourth_line'))
|
assert(io.write('Xfourth_line'))
|
||||||
io.output(io.stdout)
|
io.output(io.stdout)
|
||||||
collectgarbage() -- file should be closed by GC
|
collectgarbage() -- file should be closed by GC
|
||||||
assert(io.input() == io.stdin and rawequal(io.output(), io.stdout))
|
assert(io.input() == io.stdin and rawequal(io.output(), io.stdout))
|
||||||
@ -300,14 +300,14 @@ do -- test error returns
|
|||||||
end
|
end
|
||||||
checkerr("invalid format", io.read, "x")
|
checkerr("invalid format", io.read, "x")
|
||||||
assert(io.read(0) == "") -- not eof
|
assert(io.read(0) == "") -- not eof
|
||||||
assert(io.read(5, 'l') == '"<EFBFBD>lo"')
|
assert(io.read(5, 'l') == '"alo"')
|
||||||
assert(io.read(0) == "")
|
assert(io.read(0) == "")
|
||||||
assert(io.read() == "second line")
|
assert(io.read() == "second line")
|
||||||
local x = io.input():seek()
|
local x = io.input():seek()
|
||||||
assert(io.read() == "third line ")
|
assert(io.read() == "third line ")
|
||||||
assert(io.input():seek("set", x))
|
assert(io.input():seek("set", x))
|
||||||
assert(io.read('L') == "third line \n")
|
assert(io.read('L') == "third line \n")
|
||||||
assert(io.read(1) == "<EFBFBD>")
|
assert(io.read(1) == "X")
|
||||||
assert(io.read(string.len"fourth_line") == "fourth_line")
|
assert(io.read(string.len"fourth_line") == "fourth_line")
|
||||||
assert(io.input():seek("cur", -string.len"fourth_line"))
|
assert(io.input():seek("cur", -string.len"fourth_line"))
|
||||||
assert(io.read() == "fourth_line")
|
assert(io.read() == "fourth_line")
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
-- $Id: testes/pm.lua $
|
-- $Id: testes/pm.lua $
|
||||||
-- See Copyright Notice in file all.lua
|
-- See Copyright Notice in file all.lua
|
||||||
|
|
||||||
|
-- UTF-8 file
|
||||||
|
|
||||||
|
|
||||||
print('testing pattern matching')
|
print('testing pattern matching')
|
||||||
|
|
||||||
local function checkerror (msg, f, ...)
|
local function checkerror (msg, f, ...)
|
||||||
@ -50,6 +53,19 @@ assert(f('aLo_ALO', '%a*') == 'aLo')
|
|||||||
|
|
||||||
assert(f(" \n\r*&\n\r xuxu \n\n", "%g%g%g+") == "xuxu")
|
assert(f(" \n\r*&\n\r xuxu \n\n", "%g%g%g+") == "xuxu")
|
||||||
|
|
||||||
|
|
||||||
|
-- Adapt a pattern to UTF-8
|
||||||
|
local function PU (p)
|
||||||
|
-- break '?' into each individual byte of a character
|
||||||
|
p = string.gsub(p, "(" .. utf8.charpattern .. ")%?", function (c)
|
||||||
|
return string.gsub(c, ".", "%0?")
|
||||||
|
end)
|
||||||
|
-- change '.' to utf-8 character patterns
|
||||||
|
p = string.gsub(p, "%.", utf8.charpattern)
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
assert(f('aaab', 'a*') == 'aaa');
|
assert(f('aaab', 'a*') == 'aaa');
|
||||||
assert(f('aaa', '^.*$') == 'aaa');
|
assert(f('aaa', '^.*$') == 'aaa');
|
||||||
assert(f('aaa', 'b*') == '');
|
assert(f('aaa', 'b*') == '');
|
||||||
@ -73,16 +89,16 @@ assert(f('aaa', '^.-$') == 'aaa')
|
|||||||
assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab')
|
assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab')
|
||||||
assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab')
|
assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab')
|
||||||
assert(f('alo xo', '.o$') == 'xo')
|
assert(f('alo xo', '.o$') == 'xo')
|
||||||
assert(f(' \n isto <EFBFBD> assim', '%S%S*') == 'isto')
|
assert(f(' \n isto é assim', '%S%S*') == 'isto')
|
||||||
assert(f(' \n isto <EFBFBD> assim', '%S*$') == 'assim')
|
assert(f(' \n isto é assim', '%S*$') == 'assim')
|
||||||
assert(f(' \n isto <EFBFBD> assim', '[a-z]*$') == 'assim')
|
assert(f(' \n isto é assim', '[a-z]*$') == 'assim')
|
||||||
assert(f('um caracter ? extra', '[^%sa-z]') == '?')
|
assert(f('um caracter ? extra', '[^%sa-z]') == '?')
|
||||||
assert(f('', 'a?') == '')
|
assert(f('', 'a?') == '')
|
||||||
assert(f('<EFBFBD>', '<EFBFBD>?') == '<EFBFBD>')
|
assert(f('á', PU'á?') == 'á')
|
||||||
assert(f('<EFBFBD>bl', '<EFBFBD>?b?l?') == '<EFBFBD>bl')
|
assert(f('ábl', PU'á?b?l?') == 'ábl')
|
||||||
assert(f(' <EFBFBD>bl', '<EFBFBD>?b?l?') == '')
|
assert(f(' ábl', PU'á?b?l?') == '')
|
||||||
assert(f('aa', '^aa?a?a') == 'aa')
|
assert(f('aa', '^aa?a?a') == 'aa')
|
||||||
assert(f(']]]<EFBFBD>b', '[^]]') == '<EFBFBD>')
|
assert(f(']]]áb', '[^]]+') == 'áb')
|
||||||
assert(f("0alo alo", "%x*") == "0a")
|
assert(f("0alo alo", "%x*") == "0a")
|
||||||
assert(f("alo alo", "%C+") == "alo alo")
|
assert(f("alo alo", "%C+") == "alo alo")
|
||||||
print('+')
|
print('+')
|
||||||
@ -136,28 +152,28 @@ assert(string.match("alo xyzK", "(%w+)K") == "xyz")
|
|||||||
assert(string.match("254 K", "(%d*)K") == "")
|
assert(string.match("254 K", "(%d*)K") == "")
|
||||||
assert(string.match("alo ", "(%w*)$") == "")
|
assert(string.match("alo ", "(%w*)$") == "")
|
||||||
assert(not string.match("alo ", "(%w+)$"))
|
assert(not string.match("alo ", "(%w+)$"))
|
||||||
assert(string.find("(<EFBFBD>lo)", "%(<28>") == 1)
|
assert(string.find("(álo)", "%(á") == 1)
|
||||||
local a, b, c, d, e = string.match("<EFBFBD>lo alo", "^(((.).).* (%w*))$")
|
local a, b, c, d, e = string.match("âlo alo", PU"^(((.).). (%w*))$")
|
||||||
assert(a == '<EFBFBD>lo alo' and b == '<EFBFBD>l' and c == '<EFBFBD>' and d == 'alo' and e == nil)
|
assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil)
|
||||||
a, b, c, d = string.match('0123456789', '(.+(.?)())')
|
a, b, c, d = string.match('0123456789', '(.+(.?)())')
|
||||||
assert(a == '0123456789' and b == '' and c == 11 and d == nil)
|
assert(a == '0123456789' and b == '' and c == 11 and d == nil)
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
assert(string.gsub('<EFBFBD>lo <20>lo', '<EFBFBD>', 'x') == 'xlo xlo')
|
assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo')
|
||||||
assert(string.gsub('alo <EFBFBD>lo ', ' +$', '') == 'alo <EFBFBD>lo') -- trim
|
assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim
|
||||||
assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim
|
assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim
|
||||||
assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ')
|
assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ')
|
||||||
local t = "ab<EFBFBD> d"
|
local t = "abç d"
|
||||||
a, b = string.gsub(t, '(.)', '%1@')
|
a, b = string.gsub(t, PU'(.)', '%1@')
|
||||||
assert('@'..a == string.gsub(t, '', '@') and b == 5)
|
assert(a == "a@b@ç@ @d@" and b == 5)
|
||||||
a, b = string.gsub('ab<EFBFBD>d', '(.)', '%0@', 2)
|
a, b = string.gsub('abçd', PU'(.)', '%0@', 2)
|
||||||
assert(a == 'a@b@<EFBFBD>d' and b == 2)
|
assert(a == 'a@b@çd' and b == 2)
|
||||||
assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o')
|
assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o')
|
||||||
assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") ==
|
assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") ==
|
||||||
"xyz=abc-abc=xyz")
|
"xyz=abc-abc=xyz")
|
||||||
assert(string.gsub("abc", "%w", "%1%0") == "aabbcc")
|
assert(string.gsub("abc", "%w", "%1%0") == "aabbcc")
|
||||||
assert(string.gsub("abc", "%w+", "%0%1") == "abcabc")
|
assert(string.gsub("abc", "%w+", "%0%1") == "abcabc")
|
||||||
assert(string.gsub('<EFBFBD><EFBFBD><EFBFBD>', '$', '\0<EFBFBD><EFBFBD>') == '<EFBFBD><EFBFBD><EFBFBD>\0<EFBFBD><EFBFBD>')
|
assert(string.gsub('áéí', '$', '\0óú') == 'áéí\0óú')
|
||||||
assert(string.gsub('', '^', 'r') == 'r')
|
assert(string.gsub('', '^', 'r') == 'r')
|
||||||
assert(string.gsub('', '$', 'r') == 'r')
|
assert(string.gsub('', '$', 'r') == 'r')
|
||||||
print('+')
|
print('+')
|
||||||
@ -188,8 +204,8 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
function f(a,b) return string.gsub(a,'.',b) end
|
function f(a,b) return string.gsub(a,'.',b) end
|
||||||
assert(string.gsub("trocar tudo em |teste|b| <EFBFBD> |beleza|al|", "|([^|]*)|([^|]*)|", f) ==
|
assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) ==
|
||||||
"trocar tudo em bbbbb <EFBFBD> alalalalalal")
|
"trocar tudo em bbbbb é alalalalalal")
|
||||||
|
|
||||||
local function dostring (s) return load(s, "")() or "" end
|
local function dostring (s) return load(s, "")() or "" end
|
||||||
assert(string.gsub("alo $a='x'$ novamente $return a$",
|
assert(string.gsub("alo $a='x'$ novamente $return a$",
|
||||||
|
@ -289,7 +289,7 @@ timesort(a, limit, function(x,y) return nil end, "equal")
|
|||||||
|
|
||||||
for i,v in pairs(a) do assert(v == false) end
|
for i,v in pairs(a) do assert(v == false) end
|
||||||
|
|
||||||
AA = {"<EFBFBD>lo", "\0first :-)", "alo", "then this one", "45", "and a new"}
|
AA = {"\xE1lo", "\0first :-)", "alo", "then this one", "45", "and a new"}
|
||||||
table.sort(AA)
|
table.sort(AA)
|
||||||
check(AA)
|
check(AA)
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
-- $Id: testes/strings.lua $
|
-- $Id: testes/strings.lua $
|
||||||
-- See Copyright Notice in file all.lua
|
-- See Copyright Notice in file all.lua
|
||||||
|
|
||||||
|
-- ISO Latin encoding
|
||||||
|
|
||||||
|
|
||||||
print('testing strings and string library')
|
print('testing strings and string library')
|
||||||
|
|
||||||
local maxi <const> = math.maxinteger
|
local maxi <const> = math.maxinteger
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
-- $Id: testes/utf8.lua $
|
-- $Id: testes/utf8.lua $
|
||||||
-- See Copyright Notice in file all.lua
|
-- See Copyright Notice in file all.lua
|
||||||
|
|
||||||
|
-- UTF-8 file
|
||||||
|
|
||||||
print "testing UTF-8 library"
|
print "testing UTF-8 library"
|
||||||
|
|
||||||
local utf8 = require'utf8'
|
local utf8 = require'utf8'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user