Разработка компилятора. Стековая виртуальная машина. Состав


Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Notice: Функция get_currentuserinfo с версии 4.5.0 считается устаревшей! Используйте wp_get_current_user(). in /hlds/web/u138079p19/code4life.ru/htdocs/wp-includes/functions.php on line 3840

После рассмотрения статьи о теоретических основах стековой виртуальной машины, необходимо рассмотреть из чего состоит стековая виртуальная машина.

На протяжении долгого времени мы не могли с точностью определиться что же должно быть в виртуальной машине, и только в версии 0.9.2 сформировалось определенное понимание.

Стековая виртуальная машина состоит и функций

которые вызываются в ответ на определенную команду. Начиная с s4g 0.9.1 мы внедрили массив методов машины, где каждый элемент массива являлся определенным методом который соответствовал определенной команде:

//! тип функции исполняющей байт код
typedef void(s4g_VM::*opfunc) ();

//! массив функций исполняющих байт код (сделано для быстрого доступа)
opfunc m_aOpFunc[S4G_VM_COMMAND_LAST];

В данном случае S4G_VM_COMMAND_LAST это самый последний элемент перечисления, и как следствие содержит наибольшее число, а именно количество команд.

Затем в конструкторе виртуальной машины:

m_aOpFunc[S4G_VM_COMMAND_PUSH] = &s4g_VM::comPush;
m_aOpFunc[S4G_VM_COMMAND_POP] = &s4g_VM::comPop;
m_aOpFunc[S4G_VM_COMMAND_PRECALL] = &s4g_VM::comPrecall;
m_aOpFunc[S4G_VM_COMMAND_CALL] = &s4g_VM::comCall;

То есть теперь методы можно вызывать вот так:

(this->*(m_aOpFunc[m_vm_command])();

Где m_vm_command это команда для виртуальной машины.

Каждый вызов (в том числе и вложенный) виртуальной машины должен передавать контекст (окружение) и массив с байт-кодом на исполнение. То есть виртуальная машина в момент исполнения кода содержит определенный контекст и массив с исполняемым байт-кодом. Контекст (окружение) машине нужно для того чтобы записывать создаваемые данные и получать значения уже созданных данных.

Откуда брать контекст? Когда исполняется непосредственно код скрипта то контекст глобальный, то есть глобальное пространство имен, когда исполняется функция то должен быть ее контекст.

Стековая виртуальная машина содержит стек исполнения

Это стек для хранения данных текущего исполнения виртуальной машины. Этот стек имеет искусственное количественное ограничение. И именно в нем в момент исполнения происходят активные действия push/get/pop.

Стековая виртуальная машина имеет стек вызовов

Стек вызовов — стек хранящий информацию для возврата управления. Обычно для возврата из функций. Данный стек имеет искусственное количественное ограничение, которое можно регулировать.

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

В s4g 0.9.2 состояние виртуальной машины характеризуется следующей структурой:

//! структура описывающая сохраненное предыдущее состояние при вызове функции и содержащее имя вызванной функции
struct s4g_CallData
{
	s4g_Stack<s4g_Command>* m_pCurrArrCommand;	//!< команды выполнения
	s4g_Table *m_pTableVars;					//!< таблица с переменными (окружением)
	int m_idCurrPos2ArrCommand;					//!< позиция в стеке исполняемых команд
	ID m_idContextLastDeactivated;				//!< поcледний деактивированный контекст (id)
	ID m_idContextNew;							//!< созданный контекст (id)
	ID m_idContextExtern;						//!< подставляемый контекст для замыканий (id)
	int m_iCountCurrOpenBlocks;					//!< количество открытых блоков
	int m_iStackSize;							//!< размер стека исполнения
	s4g_Variable *m_pVarFunc;					//!< переменная со значением функции
};

Стековая виртуальная машина содержит стек аргументов вызываемых экспортированных функций

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

То есть если происходит вызов экспортированной функции то виртуальная машина складывает в стек аргументов все переданные аргументы, и затем посредством API функций предоставляет доступ к ним в хост-программе.

Стековая виртуальная машина содержит информацию об ошибке (в случае возникновения), а также функции отладки и сброса ошибки

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

Функция сброса ошибки в нашем случае совершает очистку виртуальной машины от предыдущего состояния и устанавливает ей новое состояние (как будто машина только что была создана).


Состав виртуальной машины достаточно прост и не перегружен, если машина выполняет только свои функции))

Поделиться:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*