Roberto I 3 weeks ago
parent
commit
5b179eaf6a
5 changed files with 51 additions and 28 deletions
  1. 15 14
      lcode.c
  2. 1 1
      lparser.c
  3. 1 1
      ltable.c
  4. 20 12
      manual/manual.of
  5. 14 0
      testes/gengc.lua

+ 15 - 14
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);
-  /* 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;

+ 1 - 1
lparser.c

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

+ 1 - 1
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

+ 20 - 12
manual/manual.of

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

+ 14 - 0
testes/gengc.lua

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