[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: x86 floating-point unit assembly messing up Lua
- From: Toni Spets <toni.spets@...>
- Date: Sun, 19 Jul 2009 14:07:39 +0300
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 --