<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title></title>
  <style type="text/css">code{white-space: pre;}</style>
</head>
<body>
<p>Hi Pierre,</p>
<p>On 2016-11-27 00:56, vlc-devel wrote:</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> Integer object variables use 64 bits. If lua integers are limited to 32
 bits, use floats when necessary.

 Ref #17285

 diff --git a/modules/lua/libs/variables.c b/modules/lua/libs/variables.c
 index 9957a68..17728f7 100644
 --- a/modules/lua/libs/variables.c
 +++ b/modules/lua/libs/variables.c
 @@ -50,7 +50,18 @@ static int vlclua_pushvalue( lua_State *L, int i_type, vlc_value_t val )
              lua_pushboolean( L, val.b_bool );
              break;
          case VLC_VAR_INTEGER:
 -            lua_pushinteger( L, val.i_int );
 +            /* Lua may only support 32-bit integers. If so, and the
 +             * value requires a higher range, push it as a float. We
 +             * lose some precision, but object variables are not a
 +             * recommended API for lua scripts: functionality requiring
 +             * high precision should be provided with a dedicated lua
 +             * binding instead of object variables.
 +             */
 +            if( sizeof( lua_Integer ) < sizeof( val.i_int ) &&</code></pre>
</blockquote>
<p>See next comment regarding preprocessor evaluation rather than runtime checks.</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> +                ( val.i_int < INT32_MIN || INT32_MAX < val.i_int ) )
 +                lua_pushnumber( L, (lua_Number)val.i_int );
 +            else
 +                lua_pushinteger( L, val.i_int );
              break;
          case VLC_VAR_STRING:
              lua_pushstring( L, val.psz_string );
 @@ -93,7 +104,21 @@ static int vlclua_tovalue( lua_State *L, int i_type, vlc_value_t *val )
              val->b_bool = luaL_checkboolean( L, -1 );
              break;
          case VLC_VAR_INTEGER:
 -            val->i_int = luaL_checkinteger( L, -1 );
 +            /* Lua may only support 32-bit integers. If so, we need to
 +             * get the value as a float instead so we can even know if
 +             * there would be an overflow.
 +             */
 +            if( sizeof( lua_Integer ) < sizeof( val->i_int ) )</code></pre>
</blockquote>
<p>The above, and what follows, makes more sense as a preprocessor condition, given that <code>sizeof</code> will not change during runtime (and I fear unwanted compiler diagnostics related to “always true” vs “always false”).</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> +            {
 +                lua_Number f = luaL_checknumber( L, -1 );
 +                // Calling vlc.var.set() on integer object variables with
 +                // an out-of-range float value is not handled.
 +                val->i_int = (int64_t)( f >= 0 ? f + 0.5 : f - 0.5 );</code></pre>
</blockquote>
<p><code>roundf</code> is in <code><math.h></code> starting with <code>C99</code>.</p>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;color:#500050">
<pre><code> +                if( INT32_MIN < val->i_int && val->i_int < INT32_MAX )
 +                    val->i_int = luaL_checkinteger( L, -1 );
 +            }
 +            else
 +                val->i_int = luaL_checkinteger( L, -1 );
              break;
          case VLC_VAR_STRING:
              val->psz_string = (char*)luaL_checkstring( L, -1 ); /* XXX: Beware, this only stays valid as long as (L,-1) stays in the stack */</code></pre>
</blockquote>
</body>
</html>