So, i’ve been cooking, but the kitchen is on fire. (I have no idea what i’m doing ok?), and i need help extinguishing it.
(most of this code was written in collaboration with chatGPT, which i am not proud of.)
here’s the error from the crash dump
The thread tried to read from or write to a virtual address for which it does not have the appropriate access
here’s a snippet of what i’m doing:
the function to create a tread (exposed to the lua enviroment for execution in scripts)
int newthread(lua_State* L) //creates a thread
{
if(lua_gettop(L)<1 || ( !(lua_iscfunction(L,1) || lua_isfunction(L,1) ) )){ //we need a function as the argument
return luaL_error(L,"Expected function as argument");
}
int funcref = luaL_ref(L, LUA_REGISTRYINDEX); //the function that was passed to us - get the ref to it for later.
lua_getfenv(L, -1); //get _ENV
int envref = luaL_ref(L, LUA_REGISTRYINDEX); //and store it.
context ctx; //make a new context
dmThread::Thread thread = dmThread::New(execthread, 0x80000, (void*)&ctx, "defthread");
ctx.status=THREAD_RUNNING; //status indicators.
ctx.Lstate=L; //store the lua state for later use, too.
ctx.contextaddr=&ctx; //why not?
ctx.threadthread=thread; //and store the thread for passing to other functions
ctx.enviromentref=envref;
ctx.functionref=funcref;
context** ud = (context**)lua_newuserdata(L, sizeof(context*)); //theifery from AI
*ud = &ctx; //didn't originally include the &, but the compiler says jump, i say how high.
return 1;
}
the context struct, which is also returned as userdata for passing to other thread functions.
struct context{
int status;
lua_State* Lstate;
void* contextaddr;
dmThread::Thread threadthread;
int enviromentref;
int functionref;
};
and this is the C function where the error occurs, whose pourpose is to execute the function passed to newthread
static void execthread(void* _ctx){ //the thing that is executed in a thread.
context* ctx = (context*)_ctx;
lua_rawgeti(ctx->Lstate,LUA_REGISTRYINDEX,ctx->enviromentref); //ensure it runs in the same enviroment
lua_setfenv(ctx->Lstate,-1);
lua_pop(Lstate,1)
lua_rawgeti(ctx->Lstate,LUA_REGISTRYINDEX,ctx->functionref); //get the func
lua_call(ctx->Lstate,0,0); //we are calling that function now. 0 in 0 out to make my job a bit easier. why would you need arguments anyways? use a table in _ENV.
luaL_unref(ctx->Lstate,LUA_REGISTRYINDEX,ctx->functionref);
luaL_unref(ctx->Lstate,LUA_REGISTRYINDEX,ctx->enviromentref);
ctx->status = THREAD_FINISHED;
}