Средства, изначально работающие в браузере
Спецификация байткода Кумир
Кумир имеет два режима выполнения: быстрый - используя машинный код, полученный компилятором gcc из промежуточного C99-кода, и стандартный - используя интерпретатор байт-кода. Данный документ описывает используемый байт-код.
1 Основные положения. Структура программы интерпретатора
Программа интерпретатора состоит из:таблицы констант;
таблиц глобальных переменных;
таблиц локальных переменных;
таблицы используемых внешних функций;
программного кода, являющегося набором инструкций для каждого отдельно Кумир-алгоритма.В программе данные элементы описываются в произвольном порядке. Каждый элемент определяется заголовком, данными и, при необходимости – размером элемента в программе.
Программа может иметь как бинарное, так и текстовое представление. Эти представления эквивалентны, для их преобразования предназначена утилита kumir2-as, входящая в поставку Кумир, которая преобразует текстовое представление в бинарное и наоборот.
Формальное описание бинарного и текстового представления кода будет приведено в приложениях.
Для чтения и записи байткода как в текстовом, так и в бинарном виде предназначена библиотека Bytecode, входящая в поставку Кумир, которая реализует чтение и запись структуры Bytecode::Data (описана в data.h), используя в качестве источников ввода-вывода потоки QDataStream и QTextStream.
2 Элемент программы
Под элементом программы понимаются:константа (строковое представление – „.constant”, бинарное - 0x03 );
локальная переменная („.local”, 0x01 );
глобальная переменная („.global”, 0x02 );
ссылка на внешний алгоритм („.extern”, 0x05 );
кумир-алгоритм („.function”, 0x04 ) и его три частных случая:
– главный алгоритм („.main”, 0x07 );
– программа до первого алгоритма („.init”, 0x06 );
– тестирующий алгоритм („.testing”, 0x08 ).Элемент программы - это структура Bytecode::TableElem, которая состоит из:
типа элемента;
для констант, локальных переменных и глобальных переменных – базового типа переменной, размерности массива и параметра аргумента (арг, аргрез, рез или простая переменная);
для переменных, алгоритмов и ссылок на внешние алгоритмы – номера модуля (исполнителя) – целое число от 0 до 255;
для локальных переменных и алгоритмов – уникального номера алгоритма – целое число от 0 до 65535;
для констант, переменных, алгоримов и ссылок на внешние алгоритмы – уникальный номер id – целое число от 0 до 65535;
для переменных, алгоритмов и ссылок на внешние алгоритмы – имя переменной или алгоритма – Unicode-строка;
для ссылок на внешние алгоритмы – имя модуля (plugin'а), реализующего данный модуль – ASCII-строка;
для кумир-алгоритмов (включая его частные случаи) – список инструкций.3 Инструкции
Инструкции интерпретатора имеют фиксированный размер 32 бита.Первый байт определяет тип инструкции.
Второй байт является контекстно-зависимым и может определять:
номер модуля;
таблицу для выбора значений (локальная, глобальная или константа);
номер регистра (ячейки памяти выполнителя).
Последние два байта определяют контекстно-зависимый аргумент команды.Описание инструкций приведено в приложении instructions.xls.
Тип инструкции Hex-код Второй байт Аргумент Изменение стека значений Описание NOP 0x00 Ничего не делает CALL 0x0A Номер модуля Номер алгоритма "-N-1+R" Берет из стека число аргументов N, затем N значений в порядке следования аргумент INIT 0x0C Таблица перем. Номер переменной 0 Устанавливает флаг для переменной "не определена" SETARR 0x0D Таблица перем. Номер переменной "-2*D" Устанавливает границы D-мерного массива, если он еще не определен, либо изменяет STORE 0x0E Таблица перем. Номер переменной 0 Сохраняет значение из стека в переменной. Если переменная является массивом, то с STOREARR 0x0F Таблица перем. Номер переменной "-D" Сохраняет значение из стека в элементе D-мерного массива. Индексы массива берутся LOAD 0x10 Таблица перем. Номер переменной "+1" Кладет в стек значение переменной. Если переменная является массивом, то сохраняе LOADARR 0x11 Таблица перем. Номер переменной "-D+1" Кладет в стек значение элемента D-мерного массива. Индексы массива берутся из сте SETMON 0x12 UNSETMON 0x13 JUMP 0x14 Номер инструкции 0 Выполняет безусловный переход к соответствующему номеру инструкции в текущем алго JNZ 0x15 Номер регистра Номер инструкции 0 Выполняет переход к соответствующему номеру инструкции в текущем алгоритме, если JZ 0x16 Номер регистра Номер инструкции 0 Выполняет переход к соответствующему номеру инструкции в текущем алгоритме, если POP 0x18 Номер регистра -1 Кладет значение из стека в соотвествующий регистр PUSH 0x19 Номер регистра "+1" Кладет значение соответствующего регистра в стек значений RET 0x1B 0 Выполняет возврат из текущей выполняемой функции PAUSE 0x1D ERROR 0x1E Таблица перем. Номер переменной 0 Выполняет аварийное завершение программы с текстом ошибки из соотвествующей литер LINE 0x1F Номер строки 0 Указывает отладчику на номер текущей строки программы REF 0x20 Таблица перем. Номер переменной "+1" Кладет в стек явную ссылку на указанную переменную. Используется при передаче рез REFARR 0x21 Таблица перем. Номер переменной "-2*D+1" Кладет в стек явную ссылку на элемент D-мерного массива. Индексы массива берутся SHOWREG 0x22 Номер регистра 0 Выводит на поля значение указанного регистра CLEARMARG 0x23 Номер строки 0 Очищает поля от текущей строки (включительно), до указанной (включительно). SUM 0xF1 "-1" Берет из стека два последних элемента и кладет обратно их сумму. SUB 0xF2 "-1" Берет из стека два последних элемента и кладет обратно разность предпоследнего эл MUL 0xF3 "-1" Берет из стека два последних элемента и кладет обратно их произведение. DIV 0xF4 "-1" Берет из стека два последних элемента и кладет обратно частное от деления предпос POW 0xF5 "-1" Берет из стека два последних элемента и кладет обратно предпоследний элемент в ст NEG 0xF6 0 Берет из стека элемент и кладет обратно его противоположное значение. AND 0xF7 "-1" Берет из стека два последних элемента и возвращает их логическое произведение. OR 0xF8 "-1" Берет из стека два последних элемента и возвращает их логическую сумму. EQ 0xF9 "-1" Берет из стека два последних элемента и возвращает "истина", если они равны. NEQ 0xFA "-1" Берет из стека два последних элемента и возвращает "ложь", если они равны. LS 0xFB "-1" Берет из стека два последних элемента и возвращает "истина", если предпоследний э GT 0xFC "-1" Берет из стека два последних элемента и возвращает "истина", если предпоследний э LEQ 0xFD "-1" Берет из стека два последних элемента и возвращает "истина", если предпоследний э GEQ 0xFE "-1" Берет из стека два последних элемента и возвращает "истина", если предпоследний э
Отредактировано Лис (2022-06-13 22:32:26)