diff options
| -rw-r--r-- | lcode.c | 29 | ||||
| -rw-r--r-- | lparser.c | 2 | ||||
| -rw-r--r-- | ltable.c | 2 | ||||
| -rw-r--r-- | manual/manual.of | 32 | ||||
| -rw-r--r-- | testes/gengc.lua | 14 |
5 files changed, 51 insertions, 28 deletions
| @@ -565,20 +565,20 @@ static int k2proto (FuncState *fs, TValue *key, TValue *v) { | |||
| 565 | TValue val; | 565 | TValue val; |
| 566 | Proto *f = fs->f; | 566 | Proto *f = fs->f; |
| 567 | int tag = luaH_get(fs->kcache, key, &val); /* query scanner table */ | 567 | int tag = luaH_get(fs->kcache, key, &val); /* query scanner table */ |
| 568 | int k; | ||
| 569 | if (!tagisempty(tag)) { /* is there an index there? */ | 568 | if (!tagisempty(tag)) { /* is there an index there? */ |
| 570 | k = cast_int(ivalue(&val)); | 569 | int k = cast_int(ivalue(&val)); |
| 571 | /* collisions can happen only for float keys */ | 570 | /* collisions can happen only for float keys */ |
| 572 | lua_assert(ttisfloat(key) || luaV_rawequalobj(&f->k[k], v)); | 571 | lua_assert(ttisfloat(key) || luaV_rawequalobj(&f->k[k], v)); |
| 573 | return k; /* reuse index */ | 572 | return k; /* reuse index */ |
| 574 | } | 573 | } |
| 575 | /* constant not found; create a new entry */ | 574 | else { /* constant not found; create a new entry */ |
| 576 | k = addk(fs, f, v); | 575 | int k = addk(fs, f, v); |
| 577 | /* cache it for reuse; numerical value does not need GC barrier; | 576 | /* cache it for reuse; numerical value does not need GC barrier; |
| 578 | table is not a metatable, so it does not need to invalidate cache */ | 577 | table is not a metatable, so it does not need to invalidate cache */ |
| 579 | setivalue(&val, k); | 578 | setivalue(&val, k); |
| 580 | luaH_set(fs->ls->L, fs->kcache, key, &val); | 579 | luaH_set(fs->ls->L, fs->kcache, key, &val); |
| 581 | return k; | 580 | return k; |
| 581 | } | ||
| 582 | } | 582 | } |
| 583 | 583 | ||
| 584 | 584 | ||
| @@ -604,13 +604,14 @@ static int luaK_intK (FuncState *fs, lua_Integer n) { | |||
| 604 | /* | 604 | /* |
| 605 | ** Add a float to list of constants and return its index. Floats | 605 | ** Add a float to list of constants and return its index. Floats |
| 606 | ** with integral values need a different key, to avoid collision | 606 | ** with integral values need a different key, to avoid collision |
| 607 | ** with actual integers. To that, we add to the number its smaller | 607 | ** with actual integers. To that end, we add to the number its smaller |
| 608 | ** power-of-two fraction that is still significant in its scale. | 608 | ** power-of-two fraction that is still significant in its scale. |
| 609 | ** For doubles, that would be 1/2^52. | 609 | ** (For doubles, the fraction would be 2^-52). |
| 610 | ** This method is not bulletproof: different numbers may generate the | 610 | ** This method is not bulletproof: different numbers may generate the |
| 611 | ** same key (e.g., very large numbers will overflow to 'inf') and for | 611 | ** same key (e.g., very large numbers will overflow to 'inf') and for |
| 612 | ** floats larger than 2^53 the result is still an integer. At worst, | 612 | ** floats larger than 2^53 the result is still an integer. For those |
| 613 | ** this only wastes an entry with a duplicate. | 613 | ** cases, just generate a new entry. At worst, this only wastes an entry |
| 614 | ** with a duplicate. | ||
| 614 | */ | 615 | */ |
| 615 | static int luaK_numberK (FuncState *fs, lua_Number r) { | 616 | static int luaK_numberK (FuncState *fs, lua_Number r) { |
| 616 | TValue o, kv; | 617 | TValue o, kv; |
| @@ -625,7 +626,7 @@ static int luaK_numberK (FuncState *fs, lua_Number r) { | |||
| 625 | const lua_Number k = r * (1 + q); /* key */ | 626 | const lua_Number k = r * (1 + q); /* key */ |
| 626 | lua_Integer ik; | 627 | lua_Integer ik; |
| 627 | setfltvalue(&kv, k); /* key as a TValue */ | 628 | setfltvalue(&kv, k); /* key as a TValue */ |
| 628 | if (!luaV_flttointeger(k, &ik, F2Ieq)) { /* not an integral value? */ | 629 | if (!luaV_flttointeger(k, &ik, F2Ieq)) { /* not an integer value? */ |
| 629 | int n = k2proto(fs, &kv, &o); /* use key */ | 630 | int n = k2proto(fs, &kv, &o); /* use key */ |
| 630 | if (luaV_rawequalobj(&fs->f->k[n], &o)) /* correct value? */ | 631 | if (luaV_rawequalobj(&fs->f->k[n], &o)) /* correct value? */ |
| 631 | return n; | 632 | return n; |
| @@ -1827,7 +1827,7 @@ static lu_byte getglobalattribute (LexState *ls, lu_byte df) { | |||
| 1827 | switch (kind) { | 1827 | switch (kind) { |
| 1828 | case RDKTOCLOSE: | 1828 | case RDKTOCLOSE: |
| 1829 | luaK_semerror(ls, "global variables cannot be to-be-closed"); | 1829 | luaK_semerror(ls, "global variables cannot be to-be-closed"); |
| 1830 | break; /* to avoid warnings */ | 1830 | return kind; /* to avoid warnings */ |
| 1831 | case RDKCONST: | 1831 | case RDKCONST: |
| 1832 | return GDKCONST; /* adjust kind for global variable */ | 1832 | return GDKCONST; /* adjust kind for global variable */ |
| 1833 | default: | 1833 | default: |
| @@ -156,7 +156,7 @@ static Node *hashint (const Table *t, lua_Integer i) { | |||
| 156 | ** The main computation should be just | 156 | ** The main computation should be just |
| 157 | ** n = frexp(n, &i); return (n * INT_MAX) + i | 157 | ** n = frexp(n, &i); return (n * INT_MAX) + i |
| 158 | ** but there are some numerical subtleties. | 158 | ** but there are some numerical subtleties. |
| 159 | ** In a two-complement representation, INT_MAX does not has an exact | 159 | ** In a two-complement representation, INT_MAX may not have an exact |
| 160 | ** representation as a float, but INT_MIN does; because the absolute | 160 | ** representation as a float, but INT_MIN does; because the absolute |
| 161 | ** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the | 161 | ** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the |
| 162 | ** absolute value of the product 'frexp * -INT_MIN' is smaller or equal | 162 | ** absolute value of the product 'frexp * -INT_MIN' is smaller or equal |
diff --git a/manual/manual.of b/manual/manual.of index b2765774..61dd42f2 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
| @@ -127,7 +127,8 @@ strings can contain any 8-bit value, | |||
| 127 | including @x{embedded zeros} (@Char{\0}). | 127 | including @x{embedded zeros} (@Char{\0}). |
| 128 | Lua is also encoding-agnostic; | 128 | Lua is also encoding-agnostic; |
| 129 | it makes no assumptions about the contents of a string. | 129 | it makes no assumptions about the contents of a string. |
| 130 | The length of any string in Lua must fit in a Lua integer. | 130 | The length of any string in Lua must fit in a Lua integer, |
| 131 | and the string plus a small header must fit in @id{size_t}. | ||
| 131 | 132 | ||
| 132 | Lua can call (and manipulate) functions written in Lua and | 133 | Lua can call (and manipulate) functions written in Lua and |
| 133 | functions written in C @see{functioncall}. | 134 | functions written in C @see{functioncall}. |
| @@ -1555,7 +1556,8 @@ It has the following syntax: | |||
| 1555 | exp @bnfter{,} exp @bnfopt{@bnfter{,} exp} @Rw{do} block @Rw{end}} | 1556 | exp @bnfter{,} exp @bnfopt{@bnfter{,} exp} @Rw{do} block @Rw{end}} |
| 1556 | } | 1557 | } |
| 1557 | The given identifier (@bnfNter{Name}) defines the control variable, | 1558 | The given identifier (@bnfNter{Name}) defines the control variable, |
| 1558 | which is a new read-only variable local to the loop body (@emph{block}). | 1559 | which is a new read-only (@id{const}) variable local to the loop body |
| 1560 | (@emph{block}). | ||
| 1559 | 1561 | ||
| 1560 | The loop starts by evaluating once the three control expressions. | 1562 | The loop starts by evaluating once the three control expressions. |
| 1561 | Their values are called respectively | 1563 | Their values are called respectively |
| @@ -1610,7 +1612,7 @@ works as follows. | |||
| 1610 | 1612 | ||
| 1611 | The names @rep{var_i} declare loop variables local to the loop body. | 1613 | The names @rep{var_i} declare loop variables local to the loop body. |
| 1612 | The first of these variables is the @emph{control variable}, | 1614 | The first of these variables is the @emph{control variable}, |
| 1613 | which is a read-only variable. | 1615 | which is a read-only (@id{const}) variable. |
| 1614 | 1616 | ||
| 1615 | The loop starts by evaluating @rep{explist} | 1617 | The loop starts by evaluating @rep{explist} |
| 1616 | to produce four values: | 1618 | to produce four values: |
| @@ -4083,7 +4085,7 @@ Lua will call @id{falloc} before raising the error. | |||
| 4083 | 4085 | ||
| 4084 | 4086 | ||
| 4085 | @APIEntry{const char *lua_pushfstring (lua_State *L, const char *fmt, ...);| | 4087 | @APIEntry{const char *lua_pushfstring (lua_State *L, const char *fmt, ...);| |
| 4086 | @apii{0,1,m} | 4088 | @apii{0,1,v} |
| 4087 | 4089 | ||
| 4088 | Pushes onto the stack a formatted string | 4090 | Pushes onto the stack a formatted string |
| 4089 | and returns a pointer to this string @see{constchar}. | 4091 | and returns a pointer to this string @see{constchar}. |
| @@ -4103,6 +4105,9 @@ A conversion specifier (and its corresponding extra argument) can be | |||
| 4103 | Every occurrence of @Char{%} in the string @id{fmt} | 4105 | Every occurrence of @Char{%} in the string @id{fmt} |
| 4104 | must form a valid conversion specifier. | 4106 | must form a valid conversion specifier. |
| 4105 | 4107 | ||
| 4108 | Besides memory allocation errors, | ||
| 4109 | this function may raise an error if the resulting string is too large. | ||
| 4110 | |||
| 4106 | } | 4111 | } |
| 4107 | 4112 | ||
| 4108 | @APIEntry{void lua_pushglobaltable (lua_State *L);| | 4113 | @APIEntry{void lua_pushglobaltable (lua_State *L);| |
| @@ -4135,7 +4140,7 @@ light userdata with the same @N{C address}. | |||
| 4135 | } | 4140 | } |
| 4136 | 4141 | ||
| 4137 | @APIEntry{const char *lua_pushliteral (lua_State *L, const char *s);| | 4142 | @APIEntry{const char *lua_pushliteral (lua_State *L, const char *s);| |
| 4138 | @apii{0,1,m} | 4143 | @apii{0,1,v} |
| 4139 | 4144 | ||
| 4140 | This macro is equivalent to @Lid{lua_pushstring}, | 4145 | This macro is equivalent to @Lid{lua_pushstring}, |
| 4141 | but should be used only when @id{s} is a literal string. | 4146 | 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. | |||
| 4144 | } | 4149 | } |
| 4145 | 4150 | ||
| 4146 | @APIEntry{const char *lua_pushlstring (lua_State *L, const char *s, size_t len);| | 4151 | @APIEntry{const char *lua_pushlstring (lua_State *L, const char *s, size_t len);| |
| 4147 | @apii{0,1,m} | 4152 | @apii{0,1,v} |
| 4148 | 4153 | ||
| 4149 | Pushes the string pointed to by @id{s} with size @id{len} | 4154 | Pushes the string pointed to by @id{s} with size @id{len} |
| 4150 | onto the stack. | 4155 | onto the stack. |
| @@ -4156,6 +4161,9 @@ including @x{embedded zeros}. | |||
| 4156 | 4161 | ||
| 4157 | Returns a pointer to the internal copy of the string @see{constchar}. | 4162 | Returns a pointer to the internal copy of the string @see{constchar}. |
| 4158 | 4163 | ||
| 4164 | Besides memory allocation errors, | ||
| 4165 | this function may raise an error if the string is too large. | ||
| 4166 | |||
| 4159 | } | 4167 | } |
| 4160 | 4168 | ||
| 4161 | @APIEntry{void lua_pushnil (lua_State *L);| | 4169 | @APIEntry{void lua_pushnil (lua_State *L);| |
| @@ -5015,8 +5023,8 @@ then @id{name} is set to @id{NULL}. | |||
| 5015 | @item{@id{namewhat}| | 5023 | @item{@id{namewhat}| |
| 5016 | explains the @T{name} field. | 5024 | explains the @T{name} field. |
| 5017 | The value of @T{namewhat} can be | 5025 | The value of @T{namewhat} can be |
| 5018 | @T{"global"}, @T{"local"}, @T{"method"}, | 5026 | @T{"global"}, @T{"local"}, @T{"upvalue"}, |
| 5019 | @T{"field"}, @T{"upvalue"}, or @T{""} (the empty string), | 5027 | @T{"field"}, @T{""} (the empty string), plus some other options, |
| 5020 | according to how the function was called. | 5028 | according to how the function was called. |
| 5021 | (Lua uses the empty string when no other option seems to apply.) | 5029 | (Lua uses the empty string when no other option seems to apply.) |
| 5022 | } | 5030 | } |
| @@ -6571,7 +6579,7 @@ The call always returns the previous value of the parameter. | |||
| 6571 | If the call does not give a new value, | 6579 | If the call does not give a new value, |
| 6572 | the value is left unchanged. | 6580 | the value is left unchanged. |
| 6573 | 6581 | ||
| 6574 | Lua rounds these values before storing them; | 6582 | Lua stores these values in a compressed format, |
| 6575 | so, the value returned as the previous value may not be | 6583 | so, the value returned as the previous value may not be |
| 6576 | exactly the last value set. | 6584 | exactly the last value set. |
| 6577 | } | 6585 | } |
| @@ -6585,10 +6593,10 @@ This function should not be called by a finalizer. | |||
| 6585 | } | 6593 | } |
| 6586 | 6594 | ||
| 6587 | @LibEntry{dofile ([filename])| | 6595 | @LibEntry{dofile ([filename])| |
| 6588 | Opens the named file and executes its content as a Lua chunk. | 6596 | Opens the named file and executes its content as a Lua chunk, |
| 6597 | returning all values returned by the chunk. | ||
| 6589 | When called without arguments, | 6598 | When called without arguments, |
| 6590 | @id{dofile} executes the content of the standard input (@id{stdin}). | 6599 | @id{dofile} executes the content of the standard input (@id{stdin}). |
| 6591 | Returns all values returned by the chunk. | ||
| 6592 | In case of errors, @id{dofile} propagates the error | 6600 | In case of errors, @id{dofile} propagates the error |
| 6593 | to its caller. | 6601 | to its caller. |
| 6594 | (That is, @id{dofile} does not run in protected mode.) | 6602 | (That is, @id{dofile} does not run in protected mode.) |
| @@ -6960,7 +6968,7 @@ in case of error | |||
| 6960 | (either the original error that stopped the coroutine or | 6968 | (either the original error that stopped the coroutine or |
| 6961 | errors in closing methods), | 6969 | errors in closing methods), |
| 6962 | this function returns @false plus the error object; | 6970 | this function returns @false plus the error object; |
| 6963 | otherwise ir returns @true. | 6971 | otherwise it returns @true. |
| 6964 | 6972 | ||
| 6965 | } | 6973 | } |
| 6966 | 6974 | ||
diff --git a/testes/gengc.lua b/testes/gengc.lua index ea99bdc4..6509e39d 100644 --- a/testes/gengc.lua +++ b/testes/gengc.lua | |||
| @@ -176,6 +176,20 @@ do print"testing stop-the-world collection" | |||
| 176 | assert(collectgarbage("param", "stepsize") == step) | 176 | assert(collectgarbage("param", "stepsize") == step) |
| 177 | end | 177 | end |
| 178 | 178 | ||
| 179 | |||
| 180 | if T then -- test GC parameter codification | ||
| 181 | for _, percentage in ipairs{5, 10, 12, 20, 50, 100, 200, 500} do | ||
| 182 | local param = T.codeparam(percentage) -- codify percentage | ||
| 183 | for _, value in ipairs{1, 2, 10, 100, 257, 1023, 6500, 100000} do | ||
| 184 | local exact = value*percentage // 100 | ||
| 185 | local aprox = T.applyparam(param, value) -- apply percentage | ||
| 186 | -- difference is at most 10% (+1 compensates difference due to | ||
| 187 | -- rounding to integers) | ||
| 188 | assert(math.abs(aprox - exact) <= exact/10 + 1) | ||
| 189 | end | ||
| 190 | end | ||
| 191 | end | ||
| 192 | |||
| 179 | collectgarbage(oldmode) | 193 | collectgarbage(oldmode) |
| 180 | 194 | ||
| 181 | print('OK') | 195 | print('OK') |
