[vlc-devel] [PATCH] lua: work around 32-bit integers limitation in vlc.var

Filip Roséen filip at atch.se
Sun Nov 27 21:56:13 CET 2016


Hi Pierre,

On 2016-11-27 00:56, vlc-devel wrote:

> 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 ) &&

See next comment regarding preprocessor evaluation rather than runtime
checks.

> +                ( 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 ) )

The above, and what follows, makes more sense as a preprocessor
condition, given that `sizeof` will not change during runtime (and I
fear unwanted compiler diagnostics related to "always true" vs "always
false").

> +            {
> +                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 );

`roundf` is in `<math.h>` starting with `C99`.

> +                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 */
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20161127/07cf7d7c/attachment.html>


More information about the vlc-devel mailing list