mirror of
https://github.com/lua/lua.git
synced 2024-11-24 02:33:48 +08:00
Merge branch 'master' into nextversion
This commit is contained in:
commit
9e99f3071d
153
ldebug.c
153
ldebug.c
@ -416,40 +416,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
static const char *getobjname (const Proto *p, int lastpc, int reg,
|
||||
const char **name);
|
||||
|
||||
|
||||
/*
|
||||
** Find a "name" for the constant 'c'.
|
||||
*/
|
||||
static void kname (const Proto *p, int c, const char **name) {
|
||||
TValue *kvalue = &p->k[c];
|
||||
*name = (ttisstring(kvalue)) ? getstr(tsvalue(kvalue)) : "?";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Find a "name" for the register 'c'.
|
||||
*/
|
||||
static void rname (const Proto *p, int pc, int c, const char **name) {
|
||||
const char *what = getobjname(p, pc, c, name); /* search for 'c' */
|
||||
if (!(what && *what == 'c')) /* did not find a constant name? */
|
||||
*name = "?";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Find a "name" for a 'C' value in an RK instruction.
|
||||
*/
|
||||
static void rkname (const Proto *p, int pc, Instruction i, const char **name) {
|
||||
int c = GETARG_C(i); /* key index */
|
||||
if (GETARG_k(i)) /* is 'c' a constant? */
|
||||
kname(p, c, name);
|
||||
else /* 'c' is a register */
|
||||
rname(p, pc, c, name);
|
||||
}
|
||||
|
||||
|
||||
static int filterpc (int pc, int jmptarget) {
|
||||
if (pc < jmptarget) /* is code conditional (inside a jump)? */
|
||||
@ -508,28 +474,29 @@ static int findsetreg (const Proto *p, int lastpc, int reg) {
|
||||
|
||||
|
||||
/*
|
||||
** Check whether table being indexed by instruction 'i' is the
|
||||
** environment '_ENV'
|
||||
** Find a "name" for the constant 'c'.
|
||||
*/
|
||||
static const char *gxf (const Proto *p, int pc, Instruction i, int isup) {
|
||||
int t = GETARG_B(i); /* table index */
|
||||
const char *name; /* name of indexed variable */
|
||||
if (isup) /* is an upvalue? */
|
||||
name = upvalname(p, t);
|
||||
else
|
||||
getobjname(p, pc, t, &name);
|
||||
return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
|
||||
static const char *kname (const Proto *p, int index, const char **name) {
|
||||
TValue *kvalue = &p->k[index];
|
||||
if (ttisstring(kvalue)) {
|
||||
*name = getstr(tsvalue(kvalue));
|
||||
return "constant";
|
||||
}
|
||||
else {
|
||||
*name = "?";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *getobjname (const Proto *p, int lastpc, int reg,
|
||||
const char **name) {
|
||||
int pc;
|
||||
*name = luaF_getlocalname(p, reg + 1, lastpc);
|
||||
static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
|
||||
const char **name) {
|
||||
int pc = *ppc;
|
||||
*name = luaF_getlocalname(p, reg + 1, pc);
|
||||
if (*name) /* is a local? */
|
||||
return "local";
|
||||
/* else try symbolic execution */
|
||||
pc = findsetreg(p, lastpc, reg);
|
||||
*ppc = pc = findsetreg(p, pc, reg);
|
||||
if (pc != -1) { /* could find instruction? */
|
||||
Instruction i = p->code[pc];
|
||||
OpCode op = GET_OPCODE(i);
|
||||
@ -537,18 +504,80 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
|
||||
case OP_MOVE: {
|
||||
int b = GETARG_B(i); /* move from 'b' to 'a' */
|
||||
if (b < GETARG_A(i))
|
||||
return getobjname(p, pc, b, name); /* get name for 'b' */
|
||||
return basicgetobjname(p, ppc, b, name); /* get name for 'b' */
|
||||
break;
|
||||
}
|
||||
case OP_GETUPVAL: {
|
||||
*name = upvalname(p, GETARG_B(i));
|
||||
return "upvalue";
|
||||
}
|
||||
case OP_LOADK: return kname(p, GETARG_Bx(i), name);
|
||||
case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return NULL; /* could not find reasonable name */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Find a "name" for the register 'c'.
|
||||
*/
|
||||
static void rname (const Proto *p, int pc, int c, const char **name) {
|
||||
const char *what = basicgetobjname(p, &pc, c, name); /* search for 'c' */
|
||||
if (!(what && *what == 'c')) /* did not find a constant name? */
|
||||
*name = "?";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Find a "name" for a 'C' value in an RK instruction.
|
||||
*/
|
||||
static void rkname (const Proto *p, int pc, Instruction i, const char **name) {
|
||||
int c = GETARG_C(i); /* key index */
|
||||
if (GETARG_k(i)) /* is 'c' a constant? */
|
||||
kname(p, c, name);
|
||||
else /* 'c' is a register */
|
||||
rname(p, pc, c, name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Check whether table being indexed by instruction 'i' is the
|
||||
** environment '_ENV'
|
||||
*/
|
||||
static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) {
|
||||
int t = GETARG_B(i); /* table index */
|
||||
const char *name; /* name of indexed variable */
|
||||
if (isup) /* is 't' an upvalue? */
|
||||
name = upvalname(p, t);
|
||||
else /* 't' is a register */
|
||||
basicgetobjname(p, &pc, t, &name);
|
||||
return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Extend 'basicgetobjname' to handle table accesses
|
||||
*/
|
||||
static const char *getobjname (const Proto *p, int lastpc, int reg,
|
||||
const char **name) {
|
||||
const char *kind = basicgetobjname(p, &lastpc, reg, name);
|
||||
if (kind != NULL)
|
||||
return kind;
|
||||
else if (lastpc != -1) { /* could find instruction? */
|
||||
Instruction i = p->code[lastpc];
|
||||
OpCode op = GET_OPCODE(i);
|
||||
switch (op) {
|
||||
case OP_GETTABUP: {
|
||||
int k = GETARG_C(i); /* key index */
|
||||
kname(p, k, name);
|
||||
return gxf(p, pc, i, 1);
|
||||
return isEnv(p, lastpc, i, 1);
|
||||
}
|
||||
case OP_GETTABLE: {
|
||||
int k = GETARG_C(i); /* key index */
|
||||
rname(p, pc, k, name);
|
||||
return gxf(p, pc, i, 0);
|
||||
rname(p, lastpc, k, name);
|
||||
return isEnv(p, lastpc, i, 0);
|
||||
}
|
||||
case OP_GETI: {
|
||||
*name = "integer index";
|
||||
@ -557,24 +586,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
|
||||
case OP_GETFIELD: {
|
||||
int k = GETARG_C(i); /* key index */
|
||||
kname(p, k, name);
|
||||
return gxf(p, pc, i, 0);
|
||||
}
|
||||
case OP_GETUPVAL: {
|
||||
*name = upvalname(p, GETARG_B(i));
|
||||
return "upvalue";
|
||||
}
|
||||
case OP_LOADK:
|
||||
case OP_LOADKX: {
|
||||
int b = (op == OP_LOADK) ? GETARG_Bx(i)
|
||||
: GETARG_Ax(p->code[pc + 1]);
|
||||
if (ttisstring(&p->k[b])) {
|
||||
*name = getstr(tsvalue(&p->k[b]));
|
||||
return "constant";
|
||||
}
|
||||
break;
|
||||
return isEnv(p, lastpc, i, 0);
|
||||
}
|
||||
case OP_SELF: {
|
||||
rkname(p, pc, i, name);
|
||||
rkname(p, lastpc, i, name);
|
||||
return "method";
|
||||
}
|
||||
default: break; /* go through to return NULL */
|
||||
|
31
lmathlib.c
31
lmathlib.c
@ -249,6 +249,15 @@ static int math_type (lua_State *L) {
|
||||
** ===================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
** This code uses lots of shifts. ANSI C does not allow shifts greater
|
||||
** than or equal to the width of the type being shifted, so some shifts
|
||||
** are written in convoluted ways to match that restriction. For
|
||||
** preprocessor tests, it assumes a width of 32 bits, so the maximum
|
||||
** shift there is 31 bits.
|
||||
*/
|
||||
|
||||
|
||||
/* number of binary digits in the mantissa of a float */
|
||||
#define FIGS l_floatatt(MANT_DIG)
|
||||
|
||||
@ -271,16 +280,19 @@ static int math_type (lua_State *L) {
|
||||
|
||||
/* 'long' has at least 64 bits */
|
||||
#define Rand64 unsigned long
|
||||
#define SRand64 long
|
||||
|
||||
#elif !defined(LUA_USE_C89) && defined(LLONG_MAX)
|
||||
|
||||
/* there is a 'long long' type (which must have at least 64 bits) */
|
||||
#define Rand64 unsigned long long
|
||||
#define SRand64 long long
|
||||
|
||||
#elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3
|
||||
|
||||
/* 'lua_Unsigned' has at least 64 bits */
|
||||
#define Rand64 lua_Unsigned
|
||||
#define SRand64 lua_Integer
|
||||
|
||||
#endif
|
||||
|
||||
@ -319,23 +331,30 @@ static Rand64 nextrand (Rand64 *state) {
|
||||
}
|
||||
|
||||
|
||||
/* must take care to not shift stuff by more than 63 slots */
|
||||
|
||||
|
||||
/*
|
||||
** Convert bits from a random integer into a float in the
|
||||
** interval [0,1), getting the higher FIG bits from the
|
||||
** random unsigned integer and converting that to a float.
|
||||
** Some old Microsoft compilers cannot cast an unsigned long
|
||||
** to a floating-point number, so we use a signed long as an
|
||||
** intermediary. When lua_Number is float or double, the shift ensures
|
||||
** that 'sx' is non negative; in that case, a good compiler will remove
|
||||
** the correction.
|
||||
*/
|
||||
|
||||
/* must throw out the extra (64 - FIGS) bits */
|
||||
#define shift64_FIG (64 - FIGS)
|
||||
|
||||
/* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */
|
||||
/* 2^(-FIGS) == 2^-1 / 2^(FIGS-1) */
|
||||
#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1)))
|
||||
|
||||
static lua_Number I2d (Rand64 x) {
|
||||
return (lua_Number)(trim64(x) >> shift64_FIG) * scaleFIG;
|
||||
SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG);
|
||||
lua_Number res = (lua_Number)(sx) * scaleFIG;
|
||||
if (sx < 0)
|
||||
res += 1.0; /* correct the two's complement if negative */
|
||||
lua_assert(0 <= res && res < 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* convert a 'Rand64' to a 'lua_Unsigned' */
|
||||
@ -471,8 +490,6 @@ static lua_Number I2d (Rand64 x) {
|
||||
|
||||
#else /* 32 < FIGS <= 64 */
|
||||
|
||||
/* must take care to not shift stuff by more than 31 slots */
|
||||
|
||||
/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */
|
||||
#define scaleFIG \
|
||||
(l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33)))
|
||||
|
36
ltable.c
36
ltable.c
@ -273,7 +273,7 @@ LUAI_FUNC unsigned int luaH_realasize (const Table *t) {
|
||||
return t->alimit; /* this is the size */
|
||||
else {
|
||||
unsigned int size = t->alimit;
|
||||
/* compute the smallest power of 2 not smaller than 'n' */
|
||||
/* compute the smallest power of 2 not smaller than 'size' */
|
||||
size |= (size >> 1);
|
||||
size |= (size >> 2);
|
||||
size |= (size >> 4);
|
||||
@ -772,22 +772,36 @@ static void luaH_newkey (lua_State *L, Table *t, const TValue *key,
|
||||
|
||||
/*
|
||||
** Search function for integers. If integer is inside 'alimit', get it
|
||||
** directly from the array part. Otherwise, if 'alimit' is not equal to
|
||||
** the real size of the array, key still can be in the array part. In
|
||||
** this case, try to avoid a call to 'luaH_realasize' when key is just
|
||||
** one more than the limit (so that it can be incremented without
|
||||
** changing the real size of the array).
|
||||
** directly from the array part. Otherwise, if 'alimit' is not
|
||||
** the real size of the array, the key still can be in the array part.
|
||||
** In this case, do the "Xmilia trick" to check whether 'key-1' is
|
||||
** smaller than the real size.
|
||||
** The trick works as follow: let 'p' be an integer such that
|
||||
** '2^(p+1) >= alimit > 2^p', or '2^(p+1) > alimit-1 >= 2^p'.
|
||||
** That is, 2^(p+1) is the real size of the array, and 'p' is the highest
|
||||
** bit on in 'alimit-1'. What we have to check becomes 'key-1 < 2^(p+1)'.
|
||||
** We compute '(key-1) & ~(alimit-1)', which we call 'res'; it will
|
||||
** have the 'p' bit cleared. If the key is outside the array, that is,
|
||||
** 'key-1 >= 2^(p+1)', then 'res' will have some bit on higher than 'p',
|
||||
** therefore it will be larger or equal to 'alimit', and the check
|
||||
** will fail. If 'key-1 < 2^(p+1)', then 'res' has no bit on higher than
|
||||
** 'p', and as the bit 'p' itself was cleared, 'res' will be smaller
|
||||
** than 2^p, therefore smaller than 'alimit', and the check succeeds.
|
||||
** As special cases, when 'alimit' is 0 the condition is trivially false,
|
||||
** and when 'alimit' is 1 the condition simplifies to 'key-1 < alimit'.
|
||||
** If key is 0 or negative, 'res' will have its higher bit on, so that
|
||||
** if cannot be smaller than alimit.
|
||||
*/
|
||||
const TValue *luaH_getint (Table *t, lua_Integer key) {
|
||||
if (l_castS2U(key) - 1u < t->alimit) /* 'key' in [1, t->alimit]? */
|
||||
lua_Unsigned alimit = t->alimit;
|
||||
if (l_castS2U(key) - 1u < alimit) /* 'key' in [1, t->alimit]? */
|
||||
return &t->array[key - 1];
|
||||
else if (!limitequalsasize(t) && /* key still may be in the array part? */
|
||||
(l_castS2U(key) == t->alimit + 1 ||
|
||||
l_castS2U(key) - 1u < luaH_realasize(t))) {
|
||||
else if (!isrealasize(t) && /* key still may be in the array part? */
|
||||
(((l_castS2U(key) - 1u) & ~(alimit - 1u)) < alimit)) {
|
||||
t->alimit = cast_uint(key); /* probably '#t' is here now */
|
||||
return &t->array[key - 1];
|
||||
}
|
||||
else {
|
||||
else { /* key is not in the array part; check the hash */
|
||||
Node *n = hashint(t, key);
|
||||
for (;;) { /* check whether 'key' is somewhere in the chain */
|
||||
if (keyisinteger(n) && keyival(n) == key)
|
||||
|
@ -108,7 +108,7 @@ static size_t loadUnsigned (LoadState *S, size_t limit) {
|
||||
|
||||
|
||||
static size_t loadSize (LoadState *S) {
|
||||
return loadUnsigned(S, ~(size_t)0);
|
||||
return loadUnsigned(S, MAX_SIZET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -342,20 +342,6 @@ do -- another bug (in 5.4.0)
|
||||
end
|
||||
|
||||
|
||||
if not _port then -- another bug (since 5.2)
|
||||
-- corrupted binary dump: list of upvalue names is larger than number
|
||||
-- of upvalues, overflowing the array of upvalues.
|
||||
local code =
|
||||
"\x1b\x4c\x75\x61\x55\x00\x19\x93\x0d\x0a\x1a\x0a\x04\x08\x08\x78\x56\z
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x77\x40\x00\x86\x40\z
|
||||
\x74\x65\x6d\x70\x81\x81\x01\x00\x02\x82\x48\x00\x02\x00\xc7\x00\x01\z
|
||||
\x00\x80\x80\x80\x82\x00\x00\x80\x81\x82\x78\x80\x82\x81\x86\x40\x74\z
|
||||
\x65\x6d\x70"
|
||||
|
||||
assert(load(code)) -- segfaults in previous versions
|
||||
end
|
||||
|
||||
|
||||
x = string.dump(load("x = 1; return x"))
|
||||
a = assert(load(read1(x), nil, "b"))
|
||||
assert(a() == 1 and _G.x == 1)
|
||||
|
@ -121,6 +121,9 @@ assert(not string.find(doit"aaa={13}; local bbbb=1; aaa[bbbb](3)", "'bbbb'"))
|
||||
checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)", "number")
|
||||
checkmessage("aaa=(1)..{}", "a table value")
|
||||
|
||||
-- bug in 5.4.6
|
||||
checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'")
|
||||
|
||||
_G.aaa, _G.bbbb = nil
|
||||
|
||||
-- calls
|
||||
|
Loading…
Reference in New Issue
Block a user