TenshiRuntimeState TenshiRuntimeInit(void) { TenshiRuntimeState ret; ret = (TenshiRuntimeState)(malloc(sizeof(struct _TenshiRuntimeState))); if (!ret) return NULL; ret->L = luaL_newstate(); if (!ret->L) { TenshiRuntimeDeinit(ret); return NULL; } // Load libraries TenshiRuntime_openlibs(ret->L); // Load actor library. This is special because it loads into the global // scope and not into a specific module. tenshi_open_actor(ret->L); // Load mailbox library. Similar thing. tenshi_open_mbox(ret->L); // Load get_device implementation. tenshi_open_get_device(ret->L); // Load install_trap_global implementation. tenshi_open_trap_global(ret->L); // Set up actor scheduler lua_pushcfunction(ret->L, ActorSchedulerInit); if (lua_pcall(ret->L, 0, 0, 0) != LUA_OK) { TenshiRuntimeDeinit(ret); return NULL; } // Set up preemption trick threading_setup(ret->L); // Store ourselves into the registry lua_pushstring(ret->L, RIDX_RUNTIMESTATE); lua_pushlightuserdata(ret->L, ret); lua_settable(ret->L, LUA_REGISTRYINDEX); return ret; }
TenshiRuntimeState TenshiRuntimeInit(void) { TenshiRuntimeState ret; ret = (TenshiRuntimeState)(malloc(sizeof(struct _TenshiRuntimeState))); if (!ret) return NULL; ret->L = luaL_newstate(); if (!ret->L) { TenshiRuntimeDeinit(ret); return NULL; } // Register checkxip function on ARM #ifdef __arm__ lua_setcheckxip(ret->L, lua_arm_checkxip); #endif // Load libraries TenshiRuntime_openlibs_phase1(ret->L); lua_gc(ret->L, LUA_GCCOLLECT, 0); // Load actor library. This is special because it loads into the global // scope and not into a specific module. tenshi_open_actor(ret->L); // Load mailbox library. Similar thing. tenshi_open_mbox(ret->L); // Load get_device implementation. tenshi_open_get_device(ret->L); // Load install_trap_global implementation. tenshi_open_trap_global(ret->L); TenshiRuntime_openlibs_phase2(ret->L); // Set up actor scheduler lua_pushcfunction(ret->L, ActorSchedulerInit); if (lua_pcall(ret->L, 0, 0, 0) != LUA_OK) { TenshiRuntimeDeinit(ret); return NULL; } // Set up preemption trick threading_setup(ret->L); // Store ourselves into the registry lua_pushstring(ret->L, RIDX_RUNTIMESTATE); lua_pushlightuserdata(ret->L, ret); lua_settable(ret->L, LUA_REGISTRYINDEX); // Load the code for the actor that handles reading sensor updates and // updating sensor mailboxes ret->sensor_actor = ActorCreate(ret); if (!ret->sensor_actor) { TenshiRuntimeDeinit(ret); return NULL; } int ret_ = luaL_loadbuffer(ret->sensor_actor->L, sensor_actor_lc, sizeof(sensor_actor_lc), "sensor_actor.lua"); if (ret_ != LUA_OK) { TenshiRuntimeDeinit(ret); return NULL; } // Load the code for the actor that handles reading actuator mailboxes and // updating actuators. ret->actuator_actor = ActorCreate(ret); if (!ret->actuator_actor) { TenshiRuntimeDeinit(ret); return NULL; } ret_ = luaL_loadbuffer(ret->actuator_actor->L, actuator_actor_lc, sizeof(actuator_actor_lc), "actuator_actor.lua"); if (ret_ != LUA_OK) { TenshiRuntimeDeinit(ret); return NULL; } // Construct the RIDX_CHANGED_SENSORS table lua_pushstring(ret->L, RIDX_CHANGED_SENSORS); lua_newtable(ret->L); lua_settable(ret->L, LUA_REGISTRYINDEX); // Initialize RIDX_SENSORDEVMAP as a table with weak values that will be // used to map lightuserdata to Lua objects lua_pushstring(ret->L, RIDX_SENSORDEVMAP); lua_newtable(ret->L); lua_pushstring(ret->L, "__mode"); lua_pushstring(ret->L, "v"); lua_settable(ret->L, -3); lua_pushvalue(ret->L, -1); lua_setmetatable(ret->L, -2); lua_settable(ret->L, LUA_REGISTRYINDEX); lua_gc(ret->L, LUA_GCCOLLECT, 0); return ret; }