Details
This commit is contained in:
29
lcode.c
29
lcode.c
@@ -565,20 +565,20 @@ static int k2proto (FuncState *fs, TValue *key, TValue *v) {
|
|||||||
TValue val;
|
TValue val;
|
||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
int tag = luaH_get(fs->kcache, key, &val); /* query scanner table */
|
int tag = luaH_get(fs->kcache, key, &val); /* query scanner table */
|
||||||
int k;
|
|
||||||
if (!tagisempty(tag)) { /* is there an index there? */
|
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 */
|
/* collisions can happen only for float keys */
|
||||||
lua_assert(ttisfloat(key) || luaV_rawequalobj(&f->k[k], v));
|
lua_assert(ttisfloat(key) || luaV_rawequalobj(&f->k[k], v));
|
||||||
return k; /* reuse index */
|
return k; /* reuse index */
|
||||||
}
|
}
|
||||||
/* constant not found; create a new entry */
|
else { /* constant not found; create a new entry */
|
||||||
k = addk(fs, f, v);
|
int k = addk(fs, f, v);
|
||||||
/* cache it for reuse; numerical value does not need GC barrier;
|
/* cache it for reuse; numerical value does not need GC barrier;
|
||||||
table is not a metatable, so it does not need to invalidate cache */
|
table is not a metatable, so it does not need to invalidate cache */
|
||||||
setivalue(&val, k);
|
setivalue(&val, k);
|
||||||
luaH_set(fs->ls->L, fs->kcache, key, &val);
|
luaH_set(fs->ls->L, fs->kcache, key, &val);
|
||||||
return k;
|
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
|
** Add a float to list of constants and return its index. Floats
|
||||||
** with integral values need a different key, to avoid collision
|
** 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.
|
** 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
|
** This method is not bulletproof: different numbers may generate the
|
||||||
** same key (e.g., very large numbers will overflow to 'inf') and for
|
** 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,
|
** floats larger than 2^53 the result is still an integer. For those
|
||||||
** this only wastes an entry with a duplicate.
|
** 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) {
|
static int luaK_numberK (FuncState *fs, lua_Number r) {
|
||||||
TValue o, kv;
|
TValue o, kv;
|
||||||
@@ -625,7 +626,7 @@ static int luaK_numberK (FuncState *fs, lua_Number r) {
|
|||||||
const lua_Number k = r * (1 + q); /* key */
|
const lua_Number k = r * (1 + q); /* key */
|
||||||
lua_Integer ik;
|
lua_Integer ik;
|
||||||
setfltvalue(&kv, k); /* key as a TValue */
|
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 */
|
int n = k2proto(fs, &kv, &o); /* use key */
|
||||||
if (luaV_rawequalobj(&fs->f->k[n], &o)) /* correct value? */
|
if (luaV_rawequalobj(&fs->f->k[n], &o)) /* correct value? */
|
||||||
return n;
|
return n;
|
||||||
|
|||||||
@@ -1827,7 +1827,7 @@ static lu_byte getglobalattribute (LexState *ls, lu_byte df) {
|
|||||||
switch (kind) {
|
switch (kind) {
|
||||||
case RDKTOCLOSE:
|
case RDKTOCLOSE:
|
||||||
luaK_semerror(ls, "global variables cannot be to-be-closed");
|
luaK_semerror(ls, "global variables cannot be to-be-closed");
|
||||||
break; /* to avoid warnings */
|
return kind; /* to avoid warnings */
|
||||||
case RDKCONST:
|
case RDKCONST:
|
||||||
return GDKCONST; /* adjust kind for global variable */
|
return GDKCONST; /* adjust kind for global variable */
|
||||||
default:
|
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
|
** The main computation should be just
|
||||||
** n = frexp(n, &i); return (n * INT_MAX) + i
|
** n = frexp(n, &i); return (n * INT_MAX) + i
|
||||||
** but there are some numerical subtleties.
|
** 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
|
** representation as a float, but INT_MIN does; because the absolute
|
||||||
** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
|
** 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
|
** 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}).
|
including @x{embedded zeros} (@Char{\0}).
|
||||||
Lua is also encoding-agnostic;
|
Lua is also encoding-agnostic;
|
||||||
it makes no assumptions about the contents of a string.
|
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
|
Lua can call (and manipulate) functions written in Lua and
|
||||||
functions written in C @see{functioncall}.
|
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}}
|
exp @bnfter{,} exp @bnfopt{@bnfter{,} exp} @Rw{do} block @Rw{end}}
|
||||||
}
|
}
|
||||||
The given identifier (@bnfNter{Name}) defines the control variable,
|
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.
|
The loop starts by evaluating once the three control expressions.
|
||||||
Their values are called respectively
|
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 names @rep{var_i} declare loop variables local to the loop body.
|
||||||
The first of these variables is the @emph{control variable},
|
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}
|
The loop starts by evaluating @rep{explist}
|
||||||
to produce four values:
|
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, ...);|
|
@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
|
Pushes onto the stack a formatted string
|
||||||
and returns a pointer to this string @see{constchar}.
|
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}
|
Every occurrence of @Char{%} in the string @id{fmt}
|
||||||
must form a valid conversion specifier.
|
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);|
|
@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);|
|
@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},
|
This macro is equivalent to @Lid{lua_pushstring},
|
||||||
but should be used only when @id{s} is a literal string.
|
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);|
|
@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}
|
Pushes the string pointed to by @id{s} with size @id{len}
|
||||||
onto the stack.
|
onto the stack.
|
||||||
@@ -4156,6 +4161,9 @@ including @x{embedded zeros}.
|
|||||||
|
|
||||||
Returns a pointer to the internal copy of the string @see{constchar}.
|
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);|
|
@APIEntry{void lua_pushnil (lua_State *L);|
|
||||||
@@ -5015,8 +5023,8 @@ then @id{name} is set to @id{NULL}.
|
|||||||
@item{@id{namewhat}|
|
@item{@id{namewhat}|
|
||||||
explains the @T{name} field.
|
explains the @T{name} field.
|
||||||
The value of @T{namewhat} can be
|
The value of @T{namewhat} can be
|
||||||
@T{"global"}, @T{"local"}, @T{"method"},
|
@T{"global"}, @T{"local"}, @T{"upvalue"},
|
||||||
@T{"field"}, @T{"upvalue"}, or @T{""} (the empty string),
|
@T{"field"}, @T{""} (the empty string), plus some other options,
|
||||||
according to how the function was called.
|
according to how the function was called.
|
||||||
(Lua uses the empty string when no other option seems to apply.)
|
(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,
|
If the call does not give a new value,
|
||||||
the value is left unchanged.
|
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
|
so, the value returned as the previous value may not be
|
||||||
exactly the last value set.
|
exactly the last value set.
|
||||||
}
|
}
|
||||||
@@ -6585,10 +6593,10 @@ This function should not be called by a finalizer.
|
|||||||
}
|
}
|
||||||
|
|
||||||
@LibEntry{dofile ([filename])|
|
@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,
|
When called without arguments,
|
||||||
@id{dofile} executes the content of the standard input (@id{stdin}).
|
@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
|
In case of errors, @id{dofile} propagates the error
|
||||||
to its caller.
|
to its caller.
|
||||||
(That is, @id{dofile} does not run in protected mode.)
|
(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
|
(either the original error that stopped the coroutine or
|
||||||
errors in closing methods),
|
errors in closing methods),
|
||||||
this function returns @false plus the error object;
|
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)
|
assert(collectgarbage("param", "stepsize") == step)
|
||||||
end
|
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)
|
collectgarbage(oldmode)
|
||||||
|
|
||||||
print('OK')
|
print('OK')
|
||||||
|
|||||||
Reference in New Issue
Block a user