Я работаю над очень большой структурой, предоставляющей множество алгоритмов, функций и возможностей от C / C ++ до Lua. Эта структура также предоставляет некоторые функциональные возможности, которые работают с таблицами, индексаторами и часто являются просто прокси-сервером для поведения по умолчанию, если определенное условие не выполняется.
Мой вопрос очень простой; Безопасно ли извлекать аргументы функции из функции C, т. Е. Реализации newindex в C? В настоящее время я реализую его, получив объект, который должен содержать ключ и значение, и вставив его перед ключом и значением, предоставленными метаметоду __newindex. Затем я использую lua_rawset
, чтобы установить его для объекта, который я поместил перед собой, выталкивая два аргумента функции. Это безопасно?
Я провел обширные тесты, включая тесты на контрольных стеках и мониторинг вершины стека Lua. Ни один из этих тестов не является для меня достаточно убедительным, мне бы хотелось узнать мнение других разработчиков Lua.
Я прочитал много частей документации Lua, однако, кажется, нет четкого заявления об этом (или я не нашел его). В руководстве (https://www.lua.org/manual/5.3/manual.html#lua_CFunction) указано:
Любое другое значение в стеке ниже результатов будет корректно отброшено Lua.
Однако это не отвечает на мой вопрос, если отбрасывание этих значений само по себе может вызвать проблемы.
// An example, is this safe to do? My guts say yes
int lm_entity__newindex(lua_State* L) {
luaL_checkany(L, 1); // udata
luaL_checkany(L, 2); // key
luaL_checkany(L, 3); // value
// does not manipulate the stack, merely casts lua_touserdata
auto entity = lm_entity(L, 1);
// get the members table
lua_rawgeti(L, LUA_REGISTRYINDEX, entity->members_ref);
// place before key and value (lua_rotate)
lua_insert(L, -3);
// store, in turn popping the two function arguments
lua_rawset(L, -3);
// pop members table
lua_pop(L, 1);
return 0;
}
Я ожидаю, что это будет работать безопасно, потому что при вызове функции стек восстанавливается впоследствии на основе количества параметров, переданных функции, и количества возвращаемых значений, помещенных в стек. Однако я не уверен, что выталкивание двух аргументов из стека вызовет проблемы в этом отношении, хотя мое тестирование, похоже, доказывает обратное.