This commit is contained in:
Roberto I
2025-08-09 15:08:53 -03:00
parent 8fddca81e7
commit 5b179eaf6a
5 changed files with 51 additions and 28 deletions

29
lcode.c
View File

@@ -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);
/* 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;
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;

View File

@@ -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:

View File

@@ -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

View File

@@ -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.
}

View File

@@ -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')