Details
This commit is contained in:
19
lcode.c
19
lcode.c
@@ -565,20 +565,20 @@ static int k2proto (FuncState *fs, TValue *key, TValue *v) {
|
||||
TValue val;
|
||||
Proto *f = fs->f;
|
||||
int tag = luaH_get(fs->kcache, key, &val); /* query scanner table */
|
||||
int k;
|
||||
if (!tagisempty(tag)) { /* is there an index there? */
|
||||
k = cast_int(ivalue(&val));
|
||||
int k = cast_int(ivalue(&val));
|
||||
/* collisions can happen only for float keys */
|
||||
lua_assert(ttisfloat(key) || luaV_rawequalobj(&f->k[k], v));
|
||||
return k; /* reuse index */
|
||||
}
|
||||
/* constant not found; create a new entry */
|
||||
k = addk(fs, f, v);
|
||||
else { /* constant not found; create a new entry */
|
||||
int k = addk(fs, f, v);
|
||||
/* cache it for reuse; numerical value does not need GC barrier;
|
||||
table is not a metatable, so it does not need to invalidate cache */
|
||||
setivalue(&val, k);
|
||||
luaH_set(fs->ls->L, fs->kcache, key, &val);
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -604,13 +604,14 @@ static int luaK_intK (FuncState *fs, lua_Integer n) {
|
||||
/*
|
||||
** Add a float to list of constants and return its index. Floats
|
||||
** with integral values need a different key, to avoid collision
|
||||
** with actual integers. To that, we add to the number its smaller
|
||||
** with actual integers. To that end, we add to the number its smaller
|
||||
** power-of-two fraction that is still significant in its scale.
|
||||
** For doubles, that would be 1/2^52.
|
||||
** (For doubles, the fraction would be 2^-52).
|
||||
** This method is not bulletproof: different numbers may generate the
|
||||
** same key (e.g., very large numbers will overflow to 'inf') and for
|
||||
** floats larger than 2^53 the result is still an integer. At worst,
|
||||
** this only wastes an entry with a duplicate.
|
||||
** floats larger than 2^53 the result is still an integer. For those
|
||||
** cases, just generate a new entry. At worst, this only wastes an entry
|
||||
** with a duplicate.
|
||||
*/
|
||||
static int luaK_numberK (FuncState *fs, lua_Number r) {
|
||||
TValue o, kv;
|
||||
@@ -625,7 +626,7 @@ static int luaK_numberK (FuncState *fs, lua_Number r) {
|
||||
const lua_Number k = r * (1 + q); /* key */
|
||||
lua_Integer ik;
|
||||
setfltvalue(&kv, k); /* key as a TValue */
|
||||
if (!luaV_flttointeger(k, &ik, F2Ieq)) { /* not an integral value? */
|
||||
if (!luaV_flttointeger(k, &ik, F2Ieq)) { /* not an integer value? */
|
||||
int n = k2proto(fs, &kv, &o); /* use key */
|
||||
if (luaV_rawequalobj(&fs->f->k[n], &o)) /* correct value? */
|
||||
return n;
|
||||
|
||||
@@ -1827,7 +1827,7 @@ static lu_byte getglobalattribute (LexState *ls, lu_byte df) {
|
||||
switch (kind) {
|
||||
case RDKTOCLOSE:
|
||||
luaK_semerror(ls, "global variables cannot be to-be-closed");
|
||||
break; /* to avoid warnings */
|
||||
return kind; /* to avoid warnings */
|
||||
case RDKCONST:
|
||||
return GDKCONST; /* adjust kind for global variable */
|
||||
default:
|
||||
|
||||
2
ltable.c
2
ltable.c
@@ -156,7 +156,7 @@ static Node *hashint (const Table *t, lua_Integer i) {
|
||||
** The main computation should be just
|
||||
** n = frexp(n, &i); return (n * INT_MAX) + i
|
||||
** but there are some numerical subtleties.
|
||||
** In a two-complement representation, INT_MAX does not has an exact
|
||||
** In a two-complement representation, INT_MAX may not have an exact
|
||||
** representation as a float, but INT_MIN does; because the absolute
|
||||
** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
|
||||
** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
|
||||
|
||||
@@ -127,7 +127,8 @@ strings can contain any 8-bit value,
|
||||
including @x{embedded zeros} (@Char{\0}).
|
||||
Lua is also encoding-agnostic;
|
||||
it makes no assumptions about the contents of a string.
|
||||
The length of any string in Lua must fit in a Lua integer.
|
||||
The length of any string in Lua must fit in a Lua integer,
|
||||
and the string plus a small header must fit in @id{size_t}.
|
||||
|
||||
Lua can call (and manipulate) functions written in Lua and
|
||||
functions written in C @see{functioncall}.
|
||||
@@ -1555,7 +1556,8 @@ It has the following syntax:
|
||||
exp @bnfter{,} exp @bnfopt{@bnfter{,} exp} @Rw{do} block @Rw{end}}
|
||||
}
|
||||
The given identifier (@bnfNter{Name}) defines the control variable,
|
||||
which is a new read-only variable local to the loop body (@emph{block}).
|
||||
which is a new read-only (@id{const}) variable local to the loop body
|
||||
(@emph{block}).
|
||||
|
||||
The loop starts by evaluating once the three control expressions.
|
||||
Their values are called respectively
|
||||
@@ -1610,7 +1612,7 @@ works as follows.
|
||||
|
||||
The names @rep{var_i} declare loop variables local to the loop body.
|
||||
The first of these variables is the @emph{control variable},
|
||||
which is a read-only variable.
|
||||
which is a read-only (@id{const}) variable.
|
||||
|
||||
The loop starts by evaluating @rep{explist}
|
||||
to produce four values:
|
||||
@@ -4083,7 +4085,7 @@ Lua will call @id{falloc} before raising the error.
|
||||
|
||||
|
||||
@APIEntry{const char *lua_pushfstring (lua_State *L, const char *fmt, ...);|
|
||||
@apii{0,1,m}
|
||||
@apii{0,1,v}
|
||||
|
||||
Pushes onto the stack a formatted string
|
||||
and returns a pointer to this string @see{constchar}.
|
||||
@@ -4103,6 +4105,9 @@ A conversion specifier (and its corresponding extra argument) can be
|
||||
Every occurrence of @Char{%} in the string @id{fmt}
|
||||
must form a valid conversion specifier.
|
||||
|
||||
Besides memory allocation errors,
|
||||
this function may raise an error if the resulting string is too large.
|
||||
|
||||
}
|
||||
|
||||
@APIEntry{void lua_pushglobaltable (lua_State *L);|
|
||||
@@ -4135,7 +4140,7 @@ light userdata with the same @N{C address}.
|
||||
}
|
||||
|
||||
@APIEntry{const char *lua_pushliteral (lua_State *L, const char *s);|
|
||||
@apii{0,1,m}
|
||||
@apii{0,1,v}
|
||||
|
||||
This macro is equivalent to @Lid{lua_pushstring},
|
||||
but should be used only when @id{s} is a literal string.
|
||||
@@ -4144,7 +4149,7 @@ but should be used only when @id{s} is a literal string.
|
||||
}
|
||||
|
||||
@APIEntry{const char *lua_pushlstring (lua_State *L, const char *s, size_t len);|
|
||||
@apii{0,1,m}
|
||||
@apii{0,1,v}
|
||||
|
||||
Pushes the string pointed to by @id{s} with size @id{len}
|
||||
onto the stack.
|
||||
@@ -4156,6 +4161,9 @@ including @x{embedded zeros}.
|
||||
|
||||
Returns a pointer to the internal copy of the string @see{constchar}.
|
||||
|
||||
Besides memory allocation errors,
|
||||
this function may raise an error if the string is too large.
|
||||
|
||||
}
|
||||
|
||||
@APIEntry{void lua_pushnil (lua_State *L);|
|
||||
@@ -5015,8 +5023,8 @@ then @id{name} is set to @id{NULL}.
|
||||
@item{@id{namewhat}|
|
||||
explains the @T{name} field.
|
||||
The value of @T{namewhat} can be
|
||||
@T{"global"}, @T{"local"}, @T{"method"},
|
||||
@T{"field"}, @T{"upvalue"}, or @T{""} (the empty string),
|
||||
@T{"global"}, @T{"local"}, @T{"upvalue"},
|
||||
@T{"field"}, @T{""} (the empty string), plus some other options,
|
||||
according to how the function was called.
|
||||
(Lua uses the empty string when no other option seems to apply.)
|
||||
}
|
||||
@@ -6571,7 +6579,7 @@ The call always returns the previous value of the parameter.
|
||||
If the call does not give a new value,
|
||||
the value is left unchanged.
|
||||
|
||||
Lua rounds these values before storing them;
|
||||
Lua stores these values in a compressed format,
|
||||
so, the value returned as the previous value may not be
|
||||
exactly the last value set.
|
||||
}
|
||||
@@ -6585,10 +6593,10 @@ This function should not be called by a finalizer.
|
||||
}
|
||||
|
||||
@LibEntry{dofile ([filename])|
|
||||
Opens the named file and executes its content as a Lua chunk.
|
||||
Opens the named file and executes its content as a Lua chunk,
|
||||
returning all values returned by the chunk.
|
||||
When called without arguments,
|
||||
@id{dofile} executes the content of the standard input (@id{stdin}).
|
||||
Returns all values returned by the chunk.
|
||||
In case of errors, @id{dofile} propagates the error
|
||||
to its caller.
|
||||
(That is, @id{dofile} does not run in protected mode.)
|
||||
@@ -6960,7 +6968,7 @@ in case of error
|
||||
(either the original error that stopped the coroutine or
|
||||
errors in closing methods),
|
||||
this function returns @false plus the error object;
|
||||
otherwise ir returns @true.
|
||||
otherwise it returns @true.
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -176,6 +176,20 @@ do print"testing stop-the-world collection"
|
||||
assert(collectgarbage("param", "stepsize") == step)
|
||||
end
|
||||
|
||||
|
||||
if T then -- test GC parameter codification
|
||||
for _, percentage in ipairs{5, 10, 12, 20, 50, 100, 200, 500} do
|
||||
local param = T.codeparam(percentage) -- codify percentage
|
||||
for _, value in ipairs{1, 2, 10, 100, 257, 1023, 6500, 100000} do
|
||||
local exact = value*percentage // 100
|
||||
local aprox = T.applyparam(param, value) -- apply percentage
|
||||
-- difference is at most 10% (+1 compensates difference due to
|
||||
-- rounding to integers)
|
||||
assert(math.abs(aprox - exact) <= exact/10 + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
collectgarbage(oldmode)
|
||||
|
||||
print('OK')
|
||||
|
||||
Reference in New Issue
Block a user