Skip to main content.

Archives

This is the archive for 15 November 2008

Saturday, November 15, 2008

Look at this code:

GarbageString *str = new GarbageString( vm, (const wchar_t *) Sys::dynlib_voidp_call( fa->m_fAddress, bufpos, bufsize ), -1 );
vm->retval( str );

It sounds equivalent to this:

const wchar_t *ws = (const wchar_t *) Sys::dynlib_voidp_call( fa->m_fAddress, bufpos, bufsize )
GarbageString *str = new GarbageString( vm, ws, -1 );
vm->retval( str );

But for Visual C 2005 it's not so equivalent. In release build the second one crashes; the reason is in the fact that dynlib_voidp_call() mangles with some registers via assembly, apparently, but a wise compiler should not rely on register persistence across foreign function calls. Also, the problem is in the ws variable. It seems its value gets lost between the return from dynlib_voidp_call and the call on the next line. Be warned...
Being hit once by your own decision is part of the life game, but being hit twice is more than I can stand. In the initial development of Falcon, I thought that the protection provided by the special path for load/import directive was enough to distinguish Falcon modules from system modules. I was right, but there was another aspect I didn't take into account: that Falcon modules may need to dynlink those unprotected libraries.

Example: the SDL module. The Falcon module was called sdl.so on POSIX and sdl.dll on Windows; on POSIX, system libraries as the SDL system, require a "lib" prefix, so the dynamic library needed by the Falcon module is "libsdl.so.*". Pitifully, on Windows it's not the same; SDL system is driven by SDL.dll. The Falcon module loader is anyhow able to load the proper falcon module on "load sdl" command, but the OS dynamic linker resolves the request of the module for the system SDL.dll into... a request to load itself!

As a result, Falcon SDL module is temporarily named fsdl. When the same thing happened with ODBC module, I decide that in release 0.9 we'll have a sensible suffix attached to falcon module names, for example "sdl_fm.dll", so that we can "load sdl" without confusing the module loader nor the system dynamic linker.