lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi!

I've been doing a Lua integration to the Quake 2 game engine and came across some strange optimizations in it that messes up Lua.

Failing Lua code is a simple case like:
foo = { "bar" }
print(foo[1])

That should print "bar" but instead prints "nil".

I wrote a hack that resets the FPU to it's original state before executing Lua and then setting it back to "optimized" mode. That seems to do the trick but I'm not 100% happy with it.

The question here is: why this breaks Lua and should Lua do anything from the language side to workaround situations like this?

I provided a simple C program that demonstrates the problem:

-- snip --
#include <stdio.h>
#include <stdint.h>

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

/* Lua should print "bar", instead it prints "nil" on i386 */

#define LUA_CODE_BAD "local foo = { \"bar\" } print(foo[1])"

void dolua();

int main(int argc, char **argv)
{
/* here is some i386 optimizations Quake 2 does and it breaks Lua if used with the game */
#ifdef __i386__
       uint16_t cw;

       __asm__ __volatile__( "fnstcw %0" : "=m" (cw) );

       printf( "Original FPU control word: %x\n", cw );

       if( cw & 0x300 ) {
               printf( "Setting FPU to single precision mode\n" );
               cw &= ~0x300;
}
       printf( "Setting FPU control word: %x\n", cw );

       __asm__ __volatile__( "fldcw %0" : : "m" (cw) );
#endif

       dolua();

       return 0;
}

void dolua()
{
       lua_State *lua_L;

       lua_L = lua_open();
       luaL_openlibs(lua_L);

       luaL_loadstring(lua_L, LUA_CODE_BAD);

       printf("Executing: %s\nResult: ", LUA_CODE_BAD);
       lua_pcall(lua_L, 0, 0, 0);

       lua_close(lua_L);
}
-- snap --