gifts2017

VM1C - виртуальная машина для 1С

Опубликовал Михаил Болсун (m.bolsun) в раздел Программирование - Инструментарий

Демонстрация возможностей виртуальной машины для 1С. Создаем и выполняем код модулей в режиме Предприятия в реальном времени.


Представляю свой экспериментальный проект 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. ускорить дальнейшую обработку кода в реальном времени. Так как сам процесс компиляции  занимает относительно много времени
  2. обеспечить возможность создавать и выполнять процедуры и функции в режиме 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.

Благодаря новому полноценному компилятору, Инспектор получит статический анализ и соответсвенно ряд новых возможностей:

Проверка того, что условие всегда Истинно или Ложно и что функция возвращает одно и тоже значение. Проверка не только последних неиспользованных значений переменных, но и промежуточных присвоений, с учетом циклов и ветвлений. Анализ кода в соответствии с инструкциями препроцессора (НаСервере, НаКлиенте и т.д.). Ну и многое другое. 

 

 

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Ivan Khorkov (vano-ekt) 07.06.13 16:26
не, я лучше в конфигураторе, по старинке :-)
2. Михаил Болсун (m.bolsun) 07.06.13 16:33
(1) vano-ekt, надеюсь это была шутка, т.к. цель ролика вовсе не показать супер возможности IDE "ПолеТекстовогоДокумента" :)
Конечно, штука не для типовых конфигураций. А для авторских разработок.
3. Михаил Болсун (m.bolsun) 07.06.13 16:40
Навскидку, что можно сделать. Не держать текст модуля в конфигурации или обработке, а загружать его динамически. Например с сайта. Обновил у себя, и у всех клиентов применилось :)
Думаю, много чего можно сделать, лишь бы фантазия позволяла.
4. Ivan Khorkov (vano-ekt) 07.06.13 16:58
(3) ага, фильтруем должников... И хоп!

Для Каждого Рег Из РегистрыСведений Цикл
нз = Рег.СоздатьНаборЗаписей();
нз.Записать();
КонецЦикла;
5. Михаил Болсун (m.bolsun) 07.06.13 17:00
(4) vano-ekt, а что смущает?
все можно настроить, запретить и т.д.
ну и я же не настаиваю на этом применении, это так для примера :)
6. Михаил Болсун (m.bolsun) 07.06.13 18:26
(4) vano-ekt, пока ехал домой придумал защиту от этого сценария
генерируешь пару ключей,
публичный помещаешь в обработку,
приватным на сервере подписываешь
в обработке получаешь,
проверяешь что модуль не модифицирован
выполняешь

как то так :)
7. Михаил Болсун (m.bolsun) 07.06.13 20:17
Что-то с видео не так, не показывается в публикации :(
Вставил ссылку на ролик
8. Сергей Старых (tormozit) 07.06.13 21:04
С академической точки зрения - круто. Но практического применения не вижу, т.к. вызов метода становится очень неудобным.
9. Михаил Болсун (m.bolsun) 07.06.13 21:10
(8) tormozit, но когда необходимо получить какой то конкретный результат от модуля или действие, по моему этого достаточно
Вот я и хочу, чтобы разработчики подумали, а что можно сделать, используя это. Я думаю, есть потенциал.
10. Эмиль Карапетян (amon_ra) 07.06.13 23:47
(9) m.bolsun, не ну так-то интересно, но как применить не понятно
11. Александр Капустин (kapustinag) 08.06.13 09:46
(3) m.bolsun, Действительно, круто; пытаюсь придумать практическое применение - а вот с этим тяжеловато. Скажем, в Вашем примере в комменте номер 3 - такое без проблем делается и без VM1C. Например, в каком-то меню есть вызов обработки из справочника "Внешние обработки". Если Вы изменили эту внешнюю обработку, то осталось ее разослать по клиентам и загрузить файл - и это сразу начнет работать, без перезахода клиента в 1С.
А уж "разослать и загрузить" - эта задача решается кучей способов.
12. Михаил Болсун (m.bolsun) 08.06.13 10:26
(11) kapustinag, можно расширить синтаксис языка
например добавить атрибуты модулей и методов как в .NET
типа
//[Test]
процедура Выгрузка()
...
конецпроцедуры
...Показать Скрыть


и в зависимости от атрибутов разное поведение

или

//[ВидОбработки=Анализ]
процедура ОбработатьДанные()
...
конецпроцедуры
...Показать Скрыть
13. Михаил Болсун (m.bolsun) 08.06.13 10:42
Ну и если фантазировать дальше, то мини IDE в режиме предприятия, с расширенным синтаксисом языка, типа операторов ++, +=, лямбды, перегрузка методов и разным синтаксическим сахаром
Ну это уж так, понесло меня :)
14. Ivan Khorkov (vano-ekt) 08.06.13 11:44
не ну вообще, по поводу новизны подхода - есть консоль кода, еще Г1С по-моему писанная в дветысячилохматом году
насчет практического применения... Можно действительно так распространять обновления кода. Выложил на фтп/вэбсервис/вэбсайт - клиент проверил версию, обновил. Хранение таких модулей организовать в справочнике. Опять же, все это можно организовать через существующий в ТР справочник внешних обработок.
15. Дмитрий Шерстобитов (DitriX) 08.06.13 14:16
Я до конца не смг понять - в чем фишка?
Есть же функция в 1с Выполнить, это ее аналог?
Если да, то в чем приимущество? В Скорости? Тогда какое и на сколько?
16. Михаил Болсун (m.bolsun) 08.06.13 16:41
(15) DitriX, c Выполнить такое не получится.
Идея в том, что можно на лету создавать целые модули или методы и вызывать их. получать какую-то дополнительную информацию о структуре метода, о его параметрах и т.д. Изменять их прямо на ходу.
Вообщем Reflection
http://ru.wikipedia.org/wiki/%D0%9E%D1%82%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0­%B5_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80­%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)#C.23
17. Дмитрий Шерстобитов (DitriX) 08.06.13 17:32
(16) понял, но тут очень много НО :)
18. Михаил Болсун (m.bolsun) 08.06.13 17:51
(17) DitriX, кстати тут больше вопросов опять же к разработчикам 1С, что мешает им сделать возможность Reflection как в других языках с байт кодом. Наверное то же, что мешает сделать API для конфигуратора.
19. Дмитрий Шерстобитов (DitriX) 08.06.13 19:06
(18) то что вы делаете - интересно, спору нет.
Но 1С стала такой популярной, за счет того, что программистам не надо знать отличия между абстракными класами, или смещение регистра АХ. Они не парятся о том, какое наследование и какие уровни инкапсуляции.
Мы просто пишем код, код, который решает задачи по автоматизации бизнесс процесов.

В чем приимущество вашего подхода?
При обновлениях - приимуществ нету, даже хуже будет.
Файлики находяться где то в левом месте, их тоже надо бэкапить, если хранить их в 1с, то опять таки,в каком объекте? В хранилище, ну допустим, как с ним работать?

Как вызывать контексты? Как работать отладчиком? Как быть в серверном режиме работы? А вэб? А мобильник? А линукс?

А теперь перенесите это все на 1С и ваши вопросы?

Зачем вам апи работы с конфигуратором? Ну честно. Что вы хотите из него вытягивать?
Аналог апи - веб сервисы, и работайте как хотите и безопастно :)
20. Михаил Болсун (m.bolsun) 08.06.13 19:34
(19) DitriX, да я в общем то не предлагаю никакого подхода
Просто люблю экспериментировать, и решил попробовать расширить штатные возможности. Может кто-то еще любит экспериментальные разработки.
Вот поэтому и опубликовал этот прототип, обсудить так сказать...

А API к Конфигуратору мне бы очень пригодился в проекте TurboConf, да думаю не только мне
21. Михаил (ILM) 10.06.13 18:32
Меня заинтересовала. Можно сложные алгоритмы работы делать помодульными и собирать как кубики Лего. Но скорость откомпилированных кусков требует проверки.
При отладке также можно будет остановиться на строке исполняемого модуля?
22. Михаил Болсун (m.bolsun) 10.06.13 19:19
(21) ILM, скорость, конечно будет медленнее чем в обычном режиме, т.к. работа идет через стек, но оптимизатор по возможности, старается это дело преобразовать обратно к нормальному виду, например
push 1
stloc.0
будет преобразовано в loc0=1 и т.д.
Есть определенные ситуации, где без стека е обойтись, например вызовы внутренних функций или возврат значений.
Какое будет окончательное падение скорости, пока сказать сложно, но думаю не критичное.

Режим отладки есть, но отлаживать в Конфигураторе пока сложно, т.к. вместо имен переменных используются их индексы. Но это дело поправимо, можно настроить режиме отладки, чтобы использовались родные имена. Или на крайний случай, написать обработку отладчик. Тогда можно будет отлаживать вообще не останавливая режим Предприятия.
23. Михаил (ILM) 11.06.13 23:07
Лишь бы был реальный компилятор с шифрованием...
24. Алексей Т. (CratosX) 13.06.13 16:56
Не совсем оно же, но бОльшую часть потребности перекрывает
DVD-дисковод:\1CIts\EXE\EXTREPS\UNIREPS82\UniversalSelection\Универсальны­еПодборИОбработкаОбъектов.epf
Прикрепленные файлы:
25. Валерий Агеев (awa) 13.06.13 20:39
(0) Интересная разработка.
Но лично мне многое непонятно.
Компилятор в промежуточный код VM1C_IL_Compiler (Intemediate Language Compiler)

Что такое промежуточный код? Это 1Совский байт-код или какая-то система команд собственной разработки?
Виртуальная машина VM1C позволяет, на лету, посредством JIT компилятора, скомпилировать модуль из IL-кода обратно в код понятный 1С.

Что такое понятный 1С код? Это байт-код 1С или исходный текст 1С? В связи с этим непонятно, как на самом деле происходит выполнение? Пошаговое выполнение своей виртуальной машиной своих команд, или все же каким-то образом код выполняет сама 1С (типа Выполнить)? С какими контекстами происходит выполнение? Т.е. можно ли писать модули, являющиеся расширением модуля объекта, например?
26. Михаил Болсун (m.bolsun) 13.06.13 20:50
(25) awa, промежуточный код - своя система команд, похожая на байткод .NET

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

и уже этот код, являющийся снова родным для 1С выполняется посредством Выполнить

upd: сначала написал, что контекст используется вызываемого модуля, но подумал и понял, что это не так

контекст используется модуля, где расположены методы ВМ
но думаю, можно подшаманить, чтобы использовался контекст модуля
27. Валерий Агеев (awa) 13.06.13 21:13
(26) Вот теперь понятно, спасибо. Итак, как я понял:
  • VM1C_IL_Compiler - это компилятор с языка 1С (или в будущем с расширенного языка 1С) в собственный байт-код
  • VM1C_JIT_Compiler - это декомпилятор из собственного байт-кода в исходный код 1С, но не для чтения человеком, а для исполнения, с использованием массива-стека.
  • VM1C_VM - Команда Выполнить() с небольшими наворотами для передачи/получения параметров и результатов.
28. Михаил Болсун (m.bolsun) 13.06.13 21:29
(27) awa, да все верно
только еще в функции VM1C_VM входит обработка вызовов локальных функций, вызов JIT компилятора и управление кэшем скомпилированных фрагментов, а так же функции отладки
29. John Smith (PiccaHut001) 14.06.13 10:41
Не совсем понятно, как оно работает, но всё равно замечательная весчь, на ней можна запилить ООП как 1с++ в 7.7 ?
30. Михаил Болсун (m.bolsun) 14.06.13 11:25
(29) PiccaHut001, думаю вполне можно
но вот нужно ли :)
31. Александр Орефков (orefkov) 15.06.13 00:38
А вот в С++ нет рефлекшенов - и нечего, обходимся.
Честно говоря, хотелось бы реальный пример полезности перевода кода с языка 1С на язык 1С (при чем более медленный) через промежуточный тарабарский. Потом, вы уверены, что идеально скопировали парсер кода 1С со всеми его заморочками?
32. Михаил Болсун (m.bolsun) 15.06.13 07:37
На счет реального применения хотелось бы как раз мнение разработчиков узнать.
Уверен.
33. Михаил Болсун (m.bolsun) 15.06.13 09:21
Теоретические возможные применения

Реализация Dependency Injection (Inversion of Control, IoC)
Реализация Fluent Interface
Реализация интерфейсов (ООП)
Unit Testing, Mock и т.д.
34. Андрей Овсянкин (Evil Beaver) 18.06.13 10:23
Очень интересно, думал сам что-то подобное сделать, но у вас далеко вперед шагнуло, я покурю в стороночке :)
Ну и раз проект чисто академический, может и исходники будут?
35. Михаил Болсун (m.bolsun) 18.06.13 11:02
(34) Evil Beaver, еще не решил, какое будет дальнейшее развитие проекта, поэтому об открытии исходников говорить пока рано
36. Alexander Speshilov (speshuric) 19.02.14 18:02
(0) а лексер/парсер на чем и как сделаны?
37. Михаил Болсун (m.bolsun) 20.02.14 09:16
(36) speshuric, первая версия написана в 1С, сейчас сделал версию на С# для других моих проектов на .NET
38. Евгений Рачковский (eugen91) 03.04.14 17:26
Кто уже попробовал ?
Есть такие?
опишите пожалуйста свой опыт. Нам очень интересно!
39. Михаил Болсун (m.bolsun) 03.04.14 20:51
(38) eugen91, VM1C еще не был выпущен для публичного теста. Если сможете описать сценарий использования этой технологии, я бы мог попробовать довести проект до ума. Я пока придумал только как применять эти разработки в своих продуктах.
40. Игорь Steelvan (Steelvan) 16.06.14 10:54
На этом деле можно поднять сервер защиты.
Выделяется в сети комп, при обращении к нему VM1C проверяет разрешение на работу обратившемуся и обрабатывает обращение если проверка прошла.
В ответ отправляет результат выполнения или отказ.

Я бы на этом деле такую штуку поднял, ого-го.

С подсчетом количества лицензий и прочее.
41. Михаил Болсун (m.bolsun) 16.06.14 10:59
(40) Steelvan, ну вот сегодняшняя публикация по Нетленке это и делает, только не в локальной сети и через интернет. Основа взята из VM1C
42. Денис Сидельников (dvsidelnikov) 24.10.14 00:41
Прально! Давно пора написать искусственный интеллект и заменить всех этих бухгалтеров =)))
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа