Skip to content

Commit

Permalink
Changes in cache for function constants
Browse files Browse the repository at this point in the history
In 'lcode.c', when adding constants to the list of constants of a
function, integers represent themselves in the cache and floats
with integral values get a small delta to avoid collision with
integers. (This change avoids creating artificial addresses; the old
implementation converted integers to pointers to index the cache.)
  • Loading branch information
roberto-ieru committed Mar 30, 2021
1 parent 7fbe215 commit 36de01d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
34 changes: 26 additions & 8 deletions lcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "lprefix.h"


#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
Expand Down Expand Up @@ -580,24 +581,41 @@ static int stringK (FuncState *fs, TString *s) {

/*
** Add an integer to list of constants and return its index.
** Integers use userdata as keys to avoid collision with floats with
** same value; conversion to 'void*' is used only for hashing, so there
** are no "precision" problems.
*/
static int luaK_intK (FuncState *fs, lua_Integer n) {
TValue k, o;
setpvalue(&k, cast_voidp(cast_sizet(n)));
TValue o;
setivalue(&o, n);
return addk(fs, &k, &o);
return addk(fs, &o, &o); /* use integer itself as key */
}

/*
** Add a float to list of constants and return its index.
** 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
** power-of-two fraction that is still significant in its scale.
** For doubles, that would be 1/2^52.
** (This method is not bulletproof: there may be another float
** with that value, and for floats larger than 2^53 the result is
** still an integer. At worst, this only wastes an entry with
** a duplicate.)
*/
static int luaK_numberK (FuncState *fs, lua_Number r) {
TValue o;
lua_Integer ik;
setfltvalue(&o, r);
return addk(fs, &o, &o); /* use number itself as key */
if (!luaV_flttointeger(r, &ik, F2Ieq)) /* not an integral value? */
return addk(fs, &o, &o); /* use number itself as key */
else { /* must build an alternative key */
const int nbm = l_floatatt(MANT_DIG);
const lua_Number q = l_mathop(ldexp)(1.0, -nbm + 1);
const lua_Number k = (ik == 0) ? q : r + r*q; /* new key */
TValue kv;
setfltvalue(&kv, k);
/* result is not an integral value, unless value is too large */
lua_assert(!luaV_flttointeger(k, &ik, F2Ieq) ||
l_mathop(fabs)(r) >= l_mathop(1e6));
return addk(fs, &kv, &o);
}
}


Expand Down
14 changes: 14 additions & 0 deletions testes/code.lua
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ foo = function (f, a)
checkKlist(foo, {100000, 100000.0, -100000, -100000.0})


-- floats x integers
foo = function (t, a)
t[a] = 1; t[a] = 1.0
t[a] = 1; t[a] = 1.0
t[a] = 2; t[a] = 2.0
t[a] = 0; t[a] = 0.0
t[a] = 1; t[a] = 1.0
t[a] = 2; t[a] = 2.0
t[a] = 0; t[a] = 0.0
end

checkKlist(foo, {1, 1.0, 2, 2.0, 0, 0.0})


-- testing opcodes

-- check that 'f' opcodes match '...'
Expand Down

0 comments on commit 36de01d

Please sign in to comment.