Лучший способ опустить стандартные библиотеки Lua?

Ответ - дополнение двух .

Короче говоря, Java (и большинство современных языков) не представляют собой целые числа со знаком с объявлением с знаковой величиной. Другими словами, 8-разрядное целое число не является знаковым битом, за которым следует 7-разрядное целое число без знака.

Вместо этого отрицательные целые числа представлены в системе, называемой двумя дополнениями, что позволяет упростить арифметическую обработку в аппаратном обеспечении, а также устраняет потенциальную двусмысленность наличия положительного нуля и отрицательного нуля. Побочным эффектом устранения отрицательного нуля является то, что в нижней части диапазона всегда имеется одно дополнительное отрицательное число.

Еще одно интересное свойство систем дополнений двух состоит в том, что первый бит эффективно работает в качестве индикатора знака (т. е. все числа, начинающиеся с бит 1, являются отрицательными), но следующие семь биты не должны быть интерпретированы сами по себе как беззнаковое число, к которому применяется битовый знак.

Дополнение от 2 не является ужасно сложным, но получает первоначальное хорошее сцепление с тем, что является дополнением и как и почему он работает, вероятно, выходит за рамки SO-ответа. Начните с статьи в Википедии, или в google термин для получения дополнительных ресурсов.

Чтобы попытаться кратко рассмотреть ваш запрос о -128, основная идея создания двоичного номера второго заключается в том, чтобы принять неподписанную форму номера , инвертируйте все биты и добавьте один. Таким образом, unsigned 128 - 10000000. Перевернутый, это 01111111, и добавление снова получает 10000000. Таким образом, в системе дополнений двух, 10000000 недвусмысленно -128, а не +128. Числа, большие или равные +128, просто не могут быть представлены в 8 битах с использованием системы комплемента двух, потому что они будут неоднозначными с формами отрицательных чисел.

13
задан Nick Van Brunt 8 June 2009 в 18:09
поделиться

2 ответа

См. Файл luaconf.h в наборе исходных текстов для легкого доступа к большей части конфигурации времени компиляции, такой как фактический тип, используемый для lua_Number .

См. Файл linit.c в комплекте исходных текстов для получения списка основных библиотек, которые загружаются с помощью вызова luaL_openlibs () .

Обычной практикой является копирование этого файла в исходный код вашего приложения и изменение его в соответствии с вашими потребностями, вызывая эту копию luaL_openlibs () вместо основной версии. Если вы компилируете Lua в частном порядке и не связываетесь с одним из предварительно созданных двоичных файлов библиотеки, то вы можете найти метод для выполнения эквивалента, который соответствует вашим потребностям.

Конечно, вам также не нужно компилировать или ссылку на источники любой библиотеки (например, os , найдено в loslib.c ), которую вы решили оставить вне luaL_openlibs () .

Единственная библиотека, которую вы, вероятно, не можете полностью исключить, - это базовая библиотека, которая предоставляет такие вещи, как pair () , ipairs () , pcall () , tostring () , и многие другие, которые могут быть действительно неудобными делать без. При переносе в среду, где некоторые из них проблематичны, обычно рекомендуется внимательно изучить его реализацию в lbaselib.c и либо вырезать из него функции, либо заново реализовать их в соответствии с вашими потребностями.

] Edit:

Другой подход к включению другого списка библиотек в интерпретатор - это вообще не вызывать luaL_openlibs () . Хотя предоставляется для удобства, как и все вспомогательные библиотеки, luaL_openlibs () не является обязательным. Вместо этого явно открывайте только те библиотеки, которые вам нужны.

Глава 5 справочного руководства говорит об этом:

Чтобы иметь доступ к этим библиотекам, Хост-программа C должна вызывать функция luaL_openlibs , которая открывает все стандартные библиотеки. В качестве альтернативы, он может открывать их по отдельности вызов luaopen_base (для базового библиотека), luaopen_package (для библиотека пакетов), luaopen_string (для библиотека строк), luaopen_table (для библиотеки таблиц), luaopen_math (для математической библиотеки), luaopen_io (для библиотеки ввода-вывода), luaopen_os (для операционной системы библиотека) и luaopen_debug (для библиотека отладки). Эти функции объявлено в lualib.h и не должно быть позвонили напрямую: вы должны позвонить им как и любая другая функция Lua C, например, с помощью lua_call .

Это последнее предложение иногда является источником проблем, поскольку более старые версии Lua не имели этого ограничения. Каждая функция отдельного модуля luaopen_xxx () следует тому же протоколу, который используется функцией require . Ему следует передать единственный аргумент: строку, содержащую имя, под которым известен модуль. Исключением является базовый модуль, которому передается пустая строка, потому что у него нет настоящего имени.

Вот функция, которая создает новое состояние Lua и открывает только базовую библиотеку и библиотеки пакетов:

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

lua_State *CreateBasicLua() {
    lua_State *L;

    L = luaL_newstate();
    if (L) {
        lua_pushcfunction(L, luaopen_base);
        lua_pushstring(L, "");
        lua_call(L, 1, 0);
        lua_pushcfunction(L, luaopen_package);
        lua_pushstring(L, LUA_LOADLIBNAME);
        lua_call(L, 1, 0);
    }
    return L;
}

Она возвращает новое ] lua_State в случае успеха или NULL в случае неудачи.

29
ответ дан 1 December 2019 в 18:13
поделиться

Я думаю, что этот пост отвечает на ваш вопрос, но немного больше информации по теме. Имейте в виду, что вы также можете просто 'nil' целые таблицы.

Итак, в вашем примере с библиотекой «os» вы можете выполнить команду «os = nil», а затем poof !, библиотека «os» / таблица исчезла. Выполнение "os.time ()" после этого примера вернет ошибку для несуществующей библиотеки lib / table. Более того, если вы просто хотите исключить метод «time» в «os», вы можете просто выполнить «os.time = nil».

3
ответ дан 1 December 2019 в 18:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: