Представляю свой экспериментальный проект VM1C. VM1C - это виртуальная машина, которая позволяет на лету компилировать и выполнять любые процедуры и функции, а также целые модули.
По сути, это недостающая в 1С возможность полноценного Reflection, которая присутствует на других платформах, например на .NET и позволяющая там делать по истине умопомрачительные вещи.
Для тех, кто не знаком с Reflection: Wikipedia
Описание работы
VM1C работает без использования каких-либо внешних компонент, используя только штатные возможности 1C, не зависит от платформы и конфигурации. Может добавляться в конфигурацию как в виде обработки, так и в виде общего модуля.
В состав VM1C входят:
Компилятор в промежуточный код | VM1C_IL_Compiler (Intemediate Language Compiler) |
Компилятор в понятный 1С код | VM1C_JIT_Compiler (Just-in-time Compiler) |
Сама виртуальная машина | VM1C_VM (Virtual Machine) |
Рассмотрим каждый компонент отдельно
VM1C_IL_Compiler - его задача преобразовать исходный текст модуля или метода в набор коротких ассемблерных инструкций.
Например следующий код
Для н=1 По 100 Цикл
н = н+1;
КонецЦикла;
Возврат н;
будет преобразован в набор инструкций
push 1
stloc 0
push 100
stloc 1
br ~IL_1
~IL_2: ldloc 0
push 1
add
stloc 0
ldloc 0
push 1
add
stloc 0
~IL_1: ldloc 0
ldloc 1
ble ~IL_2
~IL_0: nop
ldloc 0
ret
Это сделано, для того, что бы
- ускорить дальнейшую обработку кода в реальном времени. Так как сам процесс компиляции занимает относительно много времени
- обеспечить возможность создавать и выполнять процедуры и функции в режиме 1С Предприятия
vm1C_IL_Compiler = Обработки._VM1C_IL_Compiler.Создать();
текстМодуля = ЗагрузитьКодИзФайла("Модули\РаботаСТоварами");
модуль = vm1C_IL_Compiler.КомпилироватьМодуль(текстМодуля);
После того как у нас есть промежуточный код (далее IL-код), мы можем выполнять его в виртуальной машине.
Виртуальная машина VM1C позволяет, на лету, посредством JIT компилятора, скомпилировать модуль из IL-кода обратно в код понятный 1С. Скомпилированный код оптимизируется, сохраняется в кэш, для дальнейшего повторного использования и может быть выполнен.
vm1C_VM = Обработки._VM1C_VM.Создать();
vm1C_VM.ДобавитьМодуль("РаботаСТоварами", модуль);
параметры = Новый Массив();
параметры.Добавить("00000453");
Результат = vm1C_VM.ВызватьМетод("РаботаСТоварами", "ПолучитьЦену", параметры);
Ну а дальше все зависит от нашей фантазии. Можно, например, расширить синтаксис языка и прямо в теле функции получить список параметров
...
methodInfo = vm1C_VM.GetCurrentMethodInfo();
параметры = methodInfo["Параметры"];
...
получить код функции
байтКод = methodInfo["БайтКод"];
изменить его, добавить параметры и заново вызвать уже в измененном виде и т.д.
Заключение
Проект сейчас на стадии сырой альфа версии, поэтому выкладываю только его описание и демо-ролик.
Цель данной публикации, оценить потребность в данном продукте, на сколько он может быть полезен разработчикам, в тех случаях когда стандартных средств уже не хватает для реализации самых инновационных идей.
Если, кого-то заинтересовала данная разработка, прошу обязательно сообщить!
Демонстрация работы
http://www.youtube.com/watch?v=4I9yZIu1bj4
С уважением,
разработчик m.bolsun
(c) 2013-2014 VM1C
Update: публикация долго была в черновиках, т.к. кроме академического интереса, сразу не нашлось практического применения данному проекту. Но недавно мне удалось использовать его возможности на практике и было решено вернуть публикацию. Уже скоро технологии из этого проекта будут использоваться в новой версии Code Inspector.
Благодаря новому полноценному компилятору, Инспектор получит статический анализ и соответсвенно ряд новых возможностей:
Проверка того, что условие всегда Истинно или Ложно и что функция возвращает одно и тоже значение. Проверка не только последних неиспользованных значений переменных, но и промежуточных присвоений, с учетом циклов и ветвлений. Анализ кода в соответствии с инструкциями препроцессора (НаСервере, НаКлиенте и т.д.). Ну и многое другое.