Hi all, Mac OS X 10.5 compatibility, Lua 5.0 compatibility required (hence cannot use current batch of LuaObjc bridges.)
My lua script produces an indexed table containing tens of thousands of strings.
Basic problem: how to concat those strings with a newline separator, to one string, quickly?
Fly in ointment: even using garbage-collection friendly concat code (provided at stackoverflow) the results take far too long for this purpose. (10 seconds vs 1 minute for a brute force solution.)
Proposed solution: offload the job to Cocoa, where it can be done in a fraction of a second, using NSArray's -componentsJoinedByString method.
New fly in ointment: how to get table data from Lua to Cocoa?
The script calls a registered C function, passing it the table. The C function tries to grab the table on the stack:
// Get an NSArray of strings from the first argument on the stack (a table).
NSArray *strings = nsArrayFromIndexedTable(luaState, index_1Based);
...
// Given a simple table consisting of numbers or strings, returns an NSArray.
// Nested subtables are not followed.
NSArray * nsArrayFromIndexedTable(lua_State *L, int argIdx)
{
// (Allegedly) stops GC.
lua_setgcthreshold(L, INT_MAX);
// Arg must be a table.
luaL_checktype(L, argIdx, LUA_TTABLE);
// Get num elements in table, build an array with that many.
int count = luaL_getn(L, 1);
NSMutableArray *array = [NSMutableArray arrayWithCapacity: count];
int i;
for (i = 1; i <= count; i++) {
lua_rawgeti(L, argIdx, i);
int valueType = lua_type(L, -1);
id value = 0x00;
if (valueType is_eq LUA_TNUMBER) {
value = [NSNumber numberWithDouble:lua_tonumber(L, -1)];
} else if (valueType is_eq LUA_TSTRING) {
value = [NSString stringWithUTF8String:lua_tostring(L, -1)];
}
if (value) {
[array addObject:value];
}
}
// Resume GC
lua_setgcthreshold(L, 0); // INTERMITTENT EXC_BAD_ACCESS CRASH HERE!!!!
return array;
}
Problem: calling this function with a (very large) Lua table of strings (intermittently) results in a EXC_BAD_ACCESS.
Debugger results are sporadic; sometimes not providing anything useful, but I've been able to glean that:
If those Lua GC lines included, the crash happens at lua_setgcthreshold, near the end of the function.
But... if those Lua GC lines are commented out, the crash happens at [array addObject:value]
(NSZombieEnabled is on, but is not providing useful info.)
Any help is appreciated.