\documentclass{howto}

\usepackage[hangul,nonfrench]{dhucs}
\usepackage{dhucs-ucshyper}
\hypersetup{%
  colorlinks=true,
  plainpages=false,
}

\title{ROVM Reference 문서}
\author{정 원교}
\authoraddress{
  \strong{지구 남쪽에서}\\
  이메일 : \email{weongyo@gmail.org}
}
\date{2006.3.20}

\begin{document}
\maketitle

\begin{abstract}
  \noindent
  이 문서는 ROVM Server 의 예약된 명령어와 Opcode 들에 대한 상세한 설명을 제공하고
  있으며, ROVM 의 전체적인 구성에 대한 설명 또한 들어 있습니다.
\end{abstract}

\tableofcontents

\section{소개}
\label{sec:introduction}

ROVM 은 Remote Object Virtual Machine 의 줄임말로써, 한글로 해석하면
`원격 객체 가상 머신' 정도로 될 수 있을 것입니다.

이것은 에랑(elang)\footnote{정원교가 개인적으로 하고 있는 개발
  프로젝트이며 \url{http://www.envlang.org} 가 홈페이지입니다.  아직
  완성되지 못한 모습입니다. } 프로젝트의 한 부분으로, 가장 하위에서 어셈블리
수준의 opcode 들을 실제로 해석하고 실행하는 부분을 담당하고 있으며,
프로젝트 중 가장 중요한 요소 중 하나입니다.

ROVM 의 목적은 1) 사용자로 하여금 원격에 존재하는 객체를 읽기, 쓰기,
실행 할 수 있도록 하기 위해, 2) ROVM 서버간 통신에서의 안정성을
보장하기위해 3) 편리한 디버깅 환경을 제공하는 위해서입니다.

ROVM 가 실행되면 default port (현재 ROVM Server 의 기본 포트는
\textbf{4390} 입니다.) 를 LISTENING 하고 있으며, 요청이 왔을 
때, 그것을 처리하여 해당 결과값을 반환하게 됩니다.

\subsection{ROVM 의 특징}
\label{sec:feature}

사용자 입장에서 ROVM 을 사용함으로써 얻을 수 있는 이득에는 어떤게
있을까요?

\begin{itemize}
\item \emph{\textbf{프로그램의 크기가 매우 작습니다.}}  
  개발자가 어떻게 개발하느냐에
  따라서 다르겠지만, 모든 라이브러리의 사용을 원격에 의존할 수 있기
  때문에, 프로그램의 크기가 획기적으로 작아질 수 있습니다.

  단, 네트워크가 반드시 필요하겠지요.
\item \emph{\textbf{암호화 통신을 합니다.}} 
  ROVM Server v0.1.35a
  버전부터 모든 패킷에 대한 SSL 통신을 지원하도록 개선되었습니다.
  이제 자신의 데이타에 매우 중요한 정보가 들어 있다고 하더라도
  네트워크를 통한 전송에 있어서 안전하게 지켜낼 수 있게 되었습니다.
\item \emph{\textbf{사용자 인증 기능이 존재합니다.}}
  Anonymous 접근 기능과 사용자 인증 기능 둘다 지원하게 되었습니다.
  설정을 어떻게 하느냐에 따라서 원하는 사용자만 ROVM Server 를 사용할
  수 있도록 할 수 있습니다.
\item \emph{\textbf{편리한 Configuration 기능을 제공합니다.}}  
  ROVM Server 의 설정을 편리하게 변경할 수 있도록 구성되어 있습니다.
\end{itemize}

개발자 입장에서 본 이득에는 다음과 같은 것이 있을 것입니다.
\begin{itemize}
\item \emph{\textbf{클라이언트 프로그래밍이 쉽습니다.}} `ROVM
  Interface' 패키지를 통해서 쉽게 ROVM 에서 사용되는 opcode 를
  작성하고 서버와 통신할 수 있습니다.
\item \emph{\textbf{라이브러리 혹은 클래스의 설치가 필요없습니다.}}
  모든 라이브러리가 원격에 있기 때문에 이를 개발자 PC 에 설치할 필요가
  전혀 없습니다.  ROVM Server 에서 제공하는 라이브러리 혹은 클래스에
  대한 인터페이스 정보만 알고 있으면 그것으로 충분합니다.
\item \emph{\textbf{매우 풍부한 라이브러리를 사용할 수 있습니다.}}
  ROVM Server 의 IP 와 PORT 번호만 알면, 그 서버가 제공하는
  라이브러리를 마음껏 사용할 수 있습니다.  Unix 상의 머신에서 Windows
  의존적인 기능을 사용할 수 있고, Windows 상에서 Unix 의존적인 기능을
  사용할 수 있습니다.

  C 언어에서는 python 과 같이 자유롭게 프로그래밍 할 수 있게 된다면
  얼마나 좋을까요?  그것이 가능합니다.

  Python 에서 작성한 라이브러리 및 기능은 Python 내에서만 사용할 수
  있습니다. Perl 도 마찬가지고 Ruby 도 마찬가지입니다.  Java 도 JVM 과
  같이 동작해야 하지요.  

  하지만 ROVM 에서 작성한 라이브러리는 모든 언어에 걸쳐 똑같은
  기능으로 사용할 수 있습니다.  매력적이지 않습니까?
\end{itemize}

기업 입장에서 본 이득에는 다음과 같은 것이 있을 것입니다.
\begin{itemize}
\item \emph{\textbf{완벽하게 기업 혹은 개인의 핵심 기술을 보호할 수
    있습니다.}} 사용자가 ROVM Server 를 통해서 볼 수 있는 것은
  오직 해당 클래스 혹은 라이브러리의 인터페이스 뿐입니다.  실제 핵심
  코드가 클라이언트에 깔릴 이유가 없습니다.  사용자가 `라이브러리
  서버'를 크래킹해서 서버에 침투하지 않는한 사용자는 바이너리 코드를
  볼 수 없습니다.
\item \emph{\textbf{새로운 비지니스 모델을 만들 수 있습니다.}}  더
  이상 프로그램 혹은 라이브러리를 판매할 필요가 없습니다.  서비스를
  하면 됩니다.  ROVM Server 를 구축하여 기업의 프로그램, 
  라이브러리를 서비스하면 되는 것입니다.  업그레이드 및 패치 등
  프로그래밍과 관련된 모든 작업이 하나의 서버로 집중할 수 있습니다.

  개인적인 의견을 더한다면 사용자는 해당 프로그램 혹은 라이브러리의
  서비스를 바라지 바이너리 코드를 바라는 것이 아닙니다.  기업의 핵심
  코드를 담은 library 나 바이너리 코드가 사용자의 컴퓨터에 설치될
  이유가 없습니다.
\end{itemize}

\subsection{ROVM 의 가능성?}
\label{sec:usage}

원격 객체 가상 머신이 완전히 완성되었다고 가정을 해 봅시다.  ROVM 을
어디에 사용할 수 있을까요?  실제 사용에 대한 비전이 없다면 이
서버를 만드는 것은 무의미할 것입니다.  그럼 비전은 무엇일까요.

현재 ROVM Server 가 할 수 있는 일들을 아래에 나열하였습니다.  이를
통해서 ROVM 을 어디에 사용할 수 있을지를 파악을 쉽게 할 수 있을
것입니다.

\begin{itemize}
\item \textbf{라이브러리 서버} \\
  `라이브러리 서버'의 개념은 기업 혹은 개인이 작성한 라이브러리,
  클래스, 함수 등을 원격에서 그 기능을 그대로 이용할 수 있도록 하는
  것이 목적입니다.

  조금 WAS (Web Application Server) 서버와
  개념이 비슷할 수 있을 것 같습니다만 제 개인적인 의견으로는 WAS 의
  역활보다 훨씬 강력하고 다양한 기능을 제공할 수 있을 것이라고
  생각합니다.

  아래 섹션 \ref{sec:furthermore} 의 `ROVM 의 부족한 점' 이 보충이
  된다면 충분히 좋은 개발 환경이 될 것입니다.
\end{itemize}

위에서 나열된 것 이상으로 많은 곳에서 활용될 수 있으며, 그 가능성은
무궁무진하다고 개발자 혼자(-_-;) 생각하고 있습니다.

\subsection{ROVM 의 부족한 점}
\label{sec:furthermore}

이 섹션에서는 앞으로 ROVM Server 개발에서 보충해야 할 요소들에 대한
항목을 나열하였습니다.  또한 이를 개발해 줄 개발자의 참여도
기다립니다.

\begin{itemize}
\item \emph{\textbf{Core 라이브러리의 개발이 필요합니다.}}  지원해야
  하고 추가해야 할 기능들이 매우 많습니다.  하지만 인력 부족으로 인해
  매우 속력과 가속도가 느립니다.
\item 기타 부족한 점이 헤아릴 수 없을 정도입니다.
\end{itemize}

\subsection{라이센스}
\label{sec:license}

현재 ROVM 의 라이센스는 GPL 를 따르고 있으며 일부 코드의 경우 Apache
라이센스를 따르고 있습니다, ROVM Compiler 를 이용하여 사용자가 직접
만든 코드의 경우, Apache 라이센스를 따르게 됩니다.

XXX 위에는 저렇게 적어 놓았으나, 현재 결정된 사항도 아니며, 라이센스에
대한 지식도 별로 없는 상황에서 어떤 라이센스를 해야 할지도 모릅니다. 

\section{ROVM Debugging}
처음 ROVM 을 접하는 분들을 위해서 이 절을 남기며, 디버거 프로그램으로 GDB 를 
이용한다고 가정합니다.

디버깅을 할 때 GDB 가 뿌려주는 메세지를 정확하게 보기 위해서는 -g 옵션과 -O0 옵션이
컴파일시 CFLAGS 로 지정을 해줘야 합니다.  -O0 는 최적화를 하지 않는다는 의미로써
비록 코드의 효율성을 떨어지지만 가장 정확하게 프로그램 소스의 라인수를 지적해 내며
가장 깔끔하게 화면에 뿌려주기 때문에 추천합니다.

\begin{verbatim}
$ CFLAGS='-g -O0' ./configure
\end{verbatim}

ROVM 을 효율적으로 디버깅
하기 위해서는 디버깅의 시작 포인터를 잡는 것이 중요합니다.  그런 의미에서 ROVM
의 시작 포인터는 \$prefix/src/request.c 파일에 선언되어 있는 
rc\_process\_request () 함수가 시작점이라고 할 수 있을 것 같습니다.

이 함수를 기준으로 그 전까지의 과정은
\begin{itemize}
\item 설정 부분을 처리하여 해당 각각의 option 이 제대로 작동하도록 합니다.
\item 네트워크 socket 을 열고 bind 하고 listen 을 실시하게 됩니다.
\item thread 를 생성하되, listener 와 worker 를 구분하여 생성하고 해당 두 
  thread 간의 통신을 수행할 수 있도록 합니다.
\item Garbage Collector 가 초기화됩니다.
\end{itemize}

\noindent 가 주된 업무이며 이 함수 이후로는

\begin{itemize}
\item 사용자가 넘긴 Data 를 처리하여 그에 맞는 반환값을 Client 측에 넘기는 과정이
  존재합니다.
\item 실제 opcode 를 가상 머신상에서 실행하는 과정이 있습니다.
\item ``ENVLANG File Format'' 형식을 따르는 클래스를 로드하고 그에
  대한 관리를 하게 됩니다.
\item Garbage Collector 가 주기적으로 쓰레기값들을 청소하게 됩니다.
\end{itemize}

\noindent 가 있습니다.  아래와 같이 GDB 를 이용하여 ROVM Server 를 실행시킨 후에
ROVM Client 를 이용하여 여러가지 요청을 해보게 되면 파악이 잘 될 것입니다.

\begin{verbatim}
$ gdb src/rovm
GNU gdb 6.3-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, 
and you are welcome to change it and/or distribute copies of it 
under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  
Type "show warranty" for details.
This GDB was configured as "i386-linux"...
Using host libthread_libibrary "/lib/libthread_db.so.1".

(gdb) b rc_process_request
Breakpoint 1 at 0x804ebc1: file request.c, line 523.
(gdb) r
Starting program: /projects/rovm/src/rovm
[Thread debugging using libthread_db enabled]
[New Thread 16384 (LWP 9790)]
[New Thread 32769 (LWP 9791)]
[New Thread 16386 (LWP 9792)]
[New Thread 32771 (LWP 9793)]
[New Thread 49156 (LWP 9794)]
[New Thread 65541 (LWP 9795)]
[New Thread 81926 (LWP 9796)]
[New Thread 98311 (LWP 9797)]
[New Thread 114696 (LWP 9798)]
[Thread 16386 (LWP 9792) exited]
\end{verbatim}

\subsection{Garbage Collector 의 디버깅}
\label{sec:debuggc}

현재 Garbage Collector (이하 GC) 를 디버깅하는 방법으로 존재하는 것이
log 정보를 화면에 뿌리는 것입니다.  이와 관련된 부분은
\texttt{\$prefix/src/ext/ggc-zone.c} 파일에 선언되어 있는 GGC_DEBUG_LEVEL
매크로로써 레벌을 어느 것으로 정하느냐 따라서 화면에 출력되는 로그양이
달라지게 됩니다.

GC 에 대한 디버깅을 원하시는 분은 이 매크로의 값을 수정하여
컴파일함으로써 디비깅을 할 수 있습니다.  아래는 해당 매크로에 대한 정보입니다.

\begin{verbatim}
/* Define GGC_DEBUG_LEVEL to print debugging information.
     0: No debugging output.
     1: GC statistics only.
     2: Page-entry allocations/deallocations as well.
     3: Object allocations as well.
     4: Object marks as well.  */
#define GGC_DEBUG_LEVEL (4)
\end{verbatim}

\section{Method 의 호출}
\label{sec:methodcall}

이 절에서는 ROVM Server 에서 내부 함수를 호출하는 방식에 대하여 자세히
적도록 하겠습니다.  0.0.7a 버전에 진입하면서 `CALL' opcode 들을 통해서
내부 method 를 호출할 수 있도록 지원하고 있습니다.

현재 두가지 방식으로 method 를 호출할 수 있습니다.
\begin{itemize}
\item 기존 ROVM opcode 들의 집합인 method 의 호출
\item 확장 모듈 형식의 native method 의 호출
\end{itemize}

\subsection{일반적인 method 호출}
\label{sec:methodnormalcall}

이 호출 방식은 다른 여타 VM 과 마찬가지로 VM 에서 지원하는 opcode 들의
집합으로 구성된 것을 순차적으로 실행하게 됩니다.

이러한 과정은 \$prefix/src/class.c 파일에 선언되어 있는 rc_callmethod
() 함수를 통해서 이루어지게 됩니다.

이 호출 방식에서 집중해서 봐야 할 부분은 실제 함수가 호출될 때의,
stack 모습과 호출이 된 후의 stack 모습이며, 함수의 argument 에는
어떻게 접근할 수 있는지를 중점으로 봐야 합니다.

예를 들어 설명하도록 하겠습니다.  아래에 ROVM Compiler 에서 컴파일이
가능한 예제 코드가 있습니다.

\begin{verbatim}
.class ABCDEF
    .def __init__ (T)V
        nop
    .defend

    .def abc (TII)I
        iload 1
        iload 2
        iadd
        ireturn
    .defend
.classend
\end{verbatim}

\emph{(만약 위의 (T)V 혹은 (TII)I 와 같은 메쏘드 type 에 대한 지식이
없으시다면 ``ENVLANG File Format'' 문서를 참조하시기 바랍니다.)}

아래는 위의 ABCDEF 클래스 내부에 선언되어 있는 abc 메쏘드를 호출하는
방법입니다.  ROVM Client 에서 실행한 것입니다.

\begin{verbatim}
... new e://192.168.58.129:4390/ABCDEF
... cpush 1
... cpush 2
... call abc (TII)I
\end{verbatim}

위의 호출 방법과 위에 정의된 abc 메쏘드내에서의 argument 사용 방법에
대해서 눈여겨 보시기 바랍니다.

`CALL' opcode 코드가 호출되기 바로 직전의 stack 상태는 아래와
같았습니다.

\begin{verbatim}
[DEBUG] [Sat Feb  4 19:09:35 2006] proc_rc.c(168): #2 CHAR 0x2
[DEBUG] [Sat Feb  4 19:09:35 2006] proc_rc.c(168): #1 CHAR 0x1
[DEBUG] [Sat Feb  4 19:09:35 2006] proc_rc.c(174): #0 OBJREF 0x401e4008
\end{verbatim}

이것은 메쏘드의 인자 \texttt{(TII)} 와 배치가 똑같다는 사실을 알 수 있을
것입니다.  즉 call 을 호출하기 전의 스택은 local 변수의 첫번째,
두번째, 세번째 공간을 차기하게 되는 것입니다.

abc 메쏘드의 내용을 살펴볼 경우, 이와 같은 사실을 더욱 더 잘 알게 될
것입니다

\subsection{Native method 호출}
\label{sec:methodnativecall}

이 방식은 ROVM Server v0.0.7b 에 들어오면서 생성된 방법입니다.  즉 이
방법은 .so 나 .dll 과 같은 shared library 에 들어 있는 함수를 호출하기
위한 목적으로 제작되었습니다.

하지만 단순히 dlopen 을 통해서 열어서 실행하는 것이 아니라, ROVM
Server 를 위한 확장 모듈을 통해서 실행될 수 있습니다.

자세한 내용은 ``확장 모듈 만들기'' 문서를 살펴보기 바랍니다.  이 섹션에서는 method
호출에 관한 부분만 중점적으로 살펴볼 것입니다. 

위의 문서에서도 다루고 있지만, 짧게 언급하면 항상 native method 의
모습은 아래와 같습니다.

\begin{verbatim}
int
<methodname> (self, args, ret)
     RvObject *self;
     RvValue *args, *ret;
\end{verbatim}

위의 이 함수를 \ref{sec:methodnormalcall} 섹션에서 설명하고 있는 abc
메쏘드와 같다고 가정하겠습니다.  만약 그렇다면 아래와 같이 위의 함수
모습을 바꿔야 할 것입니다.  참고로 abc 메쏘드의 타입은 \texttt{(TII)I}
였습니다.

\begin{verbatim}
int
abc (self, args, ret)
     RvObject *self;
     RvValue *args, *ret;
\end{verbatim}

똑같은 stack 으로 위 native method 를 호출하게 되면, 위의 각 argument
의 값은 다음과 같이 채워지게 됩니다.

\begin{itemize}
\item self \\
  메쏘드 타입의 `\texttt{T}' 에 해당하며, 해당 ObjectRef 를 직접 가르키고 있습니다.
\item args \\
  이 부분은 stack slot 의 배열로써, `\texttt{II}' 에 해당하는 stack slot 배열입니다.
\item ret \\
  메쏘드가 반환하게 될 값을 지정하는 곳입니다.
\end{itemize}

``일반적인 method 호출''과 ``Native method 호출''의 다른 점은 같은
argument 를 호출되기 직전에 받게 되지만, ``일반적인 method 호출''의
경우 \textbf{local 변수 개념으로 접근할 수 있도록 지원하는 것}이며
``Native method 호출''의 경우, \textbf{한번 가공하여 사용자가 쉽게 argument 에
접근할 수 있도록 하는 것}입니다.

\section{메모리 관리 방식}
\label{sec:memory}

현재 ROVM Server 에는 3 가지 메모리 관리 방식을 가지고 있습니다.

\begin{itemize}
\item Memory Pool 을 통한 메모리 관리
\item 전형적인 malloc () 함수를 통한 메모리 관리
\item Garbage Collector 에 의한 메모리 관리
\end{itemize}

다소 복잡해 보일 수 있는 메모리 관리 방식으로 인해 코드를 이해하는데,
어려울 수 있을지 모르겠지만 왜 저렇게 3 가지 방식이나 존재하는지
이해를 하신다면 크게 어렵지 않으리라 믿습니다.

\subsection{Memory Pool 을 통한 메모리 관리}
\label{sec:memtypeapache}

이 방식이 필요한 이유는 ROVM Server 자체의 특징 때문일 것입니다.
일반적인 VM 의 경우, 특정 프로그램 하나를 실행하고 난 후, (그
프로그램이 데몬 프로그램이 아닌 이상) 종료를 하게 됩니다.  하지만 ROVM
Server 에서의 종료는 `Ticket 구조체의 소멸'의 의미밖에 없습니다.  항상
ROVM Server 는 데몬으로 떠 있으면서, 특정 포트를 통해 listening 을
하고 있습니다.

즉, 사용자의 요청을 처리하고 그것이 끝나면 연결을 끊는 방식은 memory
pool 방식을 쓸 경우, 메모리 관리에서 매우 깔끔한 형태가 됩니다.

Apache 웹 서버의 메모리 관리 방식을 이해하시면 좀 더 쉽게 다가갈 수
있을 것입니다.

ROVM Server 도 웹 서버와 비슷하게 동작할 필요가 있기 때문에,
유지보수관리가 쉬운 Memory Pool 을 적용하게 된 것입니다.  Apache
Portable Runtime (APR) 에서 제공되는 memory pool 의 설계가 잘되어 있는
것도 사용의 이유이기도 합니다.

Memory Pool 방식은 사용자 요청이 왔을 때, 처음 생성되며, 사용자의
요청이 완료되고 접속이 끊기면 자동 소멸되게 됩니다.

\subsection{전형적인 malloc () 함수를 통한 메모리 관리}
\label{sec:memtypetraditional}

이 방식이 필요한 이유는 현재 `Ticket' 개념과 관련되어 있습니다.  즉,
사용자의 요청이 끝났다고 하더라도 다음 접속을 위해서는 이전에 사용했던
메모리를 유지할 필요가 있으며, 이로 인해 전통적인 방식을 고수할 필요가
있는 것입니다.

\subsection{Garbage Collector 에 의한 메모리 관리}
\label{sec:memtypegarbage}

이 메모리 관리 방식이 필요한 이유는 구지 설명을 하지 않아도 대부분의
분들이 동의를 하실 것입니다.  대부분의 VM 이 Garbage Collector (이하
GC) 가 프로그램내에 존재하기 때문입니다.

GC 가 필요한 이유는 결국 사용자가 작성한 코드가 메모리 관리 부분에서
완전하지 않기 때문에 사용되는 것입니다.  VM 은 엉망으로 만든
프로그램을 돌리고 난 후에도, 계속 다른 코드들을 실행할 수 있어야 하며
안전하게 메모리를 모두 해제해 줘야 할 의무가 있기 때문입니다.

아래 \ref{sec:garbagetarget} 섹션을 보실 경우, 현재 ROVM Server 에서
GC 의 대상이 되는 항목을 보실수 있을 것입니다.

\section{Garbage Collection}
\label{sec:garbage}

이 절에서는 ROVM Server 에서 사용하는 Garbage Collection 과 이에 대한
구현 정책에 대해서 설명하도록 하겠습니다.

현재 ROVM Server 에서 Garbage Collection 와 관련된 파일들은 아래의 세
파일이 존재합니다.

\begin{itemize}
\item \$prefix/src/gc.c
\item \$prefix/src/gc.h
\item \$prefix/src/ext/ggc-zone.c
\end{itemize}

사용되는 Garbage Collection (이하 GC) 루틴은 전형적인 mark-sweep 알고리즘이며,
이에 대한 자세한 구현은 \texttt{\$prefix/src/ext/ggc-zone.c} 파일에
표현되어 있습니다.  위 ggc-zone.c 파일은 GCC 4.0.2 버전에 포함된 GC
버전입니다.  원래는 많은 전역 변수와 GCC 에 알맞게 환경이 조성되어
있었어나, ROVM 개발자에 의해 ROVM Server 에 맞게 변형되었습니다.

\texttt{\$prefix/src/gc.[ch]} 파일의 경우, 실제 ROVM Server 에서
사용되는 인터페이스를 구현해 놓은 부분입니다.

ROVM Server 의 다른 .c 소스들은 직접적으로
\texttt{\$prefix/src/ext/ggc-zone.c} 에 선언되어 있는 함수나 헤더들을
접근하지 않으며, 모든 접근은 \texttt{\$prefix/src/gc.[ch]} 을 통해
이루어집니다.

\subsection{할당, 해제, 점검}
\label{sec:allocfreecheck}

GC 메모리 할당 함수에 대한 prototype 입니다.  이 함수 외에도 gc_calloc
() 와 같은 함수가 존재합니다.  gc_alloc 은 malloc 와 비슷한 역활을
하고 gc_calloc 는 calloc 와 비슷한 역활을 합니다.
\begin{verbatim}
void *
gc_alloc (r, size)
     struct rovm *r;
     size_t size;
\end{verbatim}

GC 메모리 해제에 대한 prototype 입니다.  이 함수를 호출한다고 해서
바로 메모리가 해제되는 것이 아니라, 실제 Garbage Collection 이
이루어진 후에야 실제로 메모리가 해제되게 됩니다.
\begin{verbatim}
void
gc_free (p)
     void *p;
\end{verbatim}

점검의 경우, Garbage Collection Thread 에 의해 주기적으로 호출되게
됩니다.

\subsection{현재 Garbage Collector 의 대상}
\label{sec:garbagetarget}

현재 ROVM Server 의 Garbage Collector 의 메모리 관리 대상이 되는
항목은 아래와 같은 것들입니다.

\begin{itemize}
\item Object Reference (ObjectRef) \\
  `NEW' opcode 를 통해서 매우 빈번히 할당되는 메모리 공간입니다.
\item String Reference (StringRef) \\
  `SPUSH' opcode 와 같은 문자열이 필요한 부분에서 생성될 수 있습니다.
\item Array Reference (ArrayRef) \\
  `NEWARRAY' opcode 를 통해서 생성될 수 있으며, 배열을 위한 공간을 제공합니다
\end{itemize}

위의 세 Reference 는 모두 생성되는 순간에 객체화가 이루어지도록 되어
있습니다.  그리고 서로 크게 다른 것은 아니지만, StringRef 와 ArrayRef
의 경우, 특정 변수의 경우 특별하게 처리되는 예외 사항이 존재합니다.

\subsection{Garbage Collection 전략}
\label{sec:garbagestrategy}

성공적이고 안정적인 Garbage Collection 을 수행하기 위해서 현재 ROVM
Server 에서는 Delayed Stack Slot 개념을 이용하여 아래에서 설명할 각 요소에 대한 전략에
사용하고 있습니다.  (`\texttt{Delayed Stack Slot}' 에 대한 자세한
설명은 \ref{sec:delayedstackslot} 섹션에서 다루고 있습니다.)

Delayed Stack Slot 개념이란 Ticket Tree 에 존재하는 Ticket 구조체들의 각
요소를 안정적으로 점검하기 위해 도입된 것으로 \texttt{gc_alloc ()} 에서 할당된 시점과 이 값이
Ticket Stack Slot 에 등록되는 시점에 매우 작은 시간 차이가 있기 때문에
이로 발생할 수 있는 예외 사항을 제거하기 위해서 적용되었습니다.  즉,
\texttt{gc_alloc ()} 함수에 의해 GC 메모리가 할당되는 순간 메모리
포인터가 Delayed Stack Slot 에 들어가 있다가 Ticket 구조체의 Stack 에
완전히 로드된 후, clear 되는 것을 말합니다.

\begin{enumerate}
\item Object Reference 에 대한 Garbage Collection 전략 \\
  모든 ObjectRef 는 Ticket 구조체의 Stack 슬롯에 들어가도록 설계
  되어 있습니다.

  즉, 만약 ObjectRef 가 살아있는 것이라면
\begin{verbatim}
검색범위 = (Ticket 구조체의 sp 변수 - Ticket 구조체의 stack 변수)
검색범위 += (Ticket 구조체의 ret 변수)
\end{verbatim}
  위의 검색범위에 항상 들어가 있을 것입니다.  만약 위 범위에 존재하지
  않는다면 죽은 ObjectRef 일 것입니다.

  검색범위의 Stack 슬롯에서 STACK_TYPE (NODE) 이 STACK_TYPE_OBJREF
  와 STACK_TYPE_ARRAYREF 인 것만 marking 을 하게 됩니다.  
  나머지 marking 이 되지 않는 것들은 모두 메모리 해제될 것입니다.
  
  여기서 하나 더 생각해야할 문제가 생겼는데, ``ENVLANG File Format'' v0.2
  에 들어서면서 클래스에 Field 값이 생겼다는 사실입니다.  이로 인해서
  Field 값에 또한 GC 메모리가 설정될 수 있기 때문에, 각각의 ObjectRef 에서
  해당 field 들을 점검한 후, 내부에 STACK_TYPE_OBJREF 와 STACK_TYPE_ARRAYREF
  가 설정되어 있으면 그것 또한 marking 을 해줘야 하는 부분을 생각해야
  합니다.
  
  만약 Garbage Collection 이 이루어지는 동안, 다른 쓰레드에 의해 sp
  값이 변경되게 되면 그것은 문제가 되지 않습니다.  왜냐하면 아래와 같은
  경우가 존재할 수 있기 때문입니다.

  \begin{itemize}
  \item 만약 sp 변경된다고 하더라고, 살아있는 ObjectRef 는 그대로 marking
    이 될 것이며, 죽은 ObjectRef 가 marking 이 그 때 안되더라도, 다음
    Garbage Collection 에서는 사라질 것이다.
  \end{itemize}
\item Array Reference 에 대한 Garbage Collection 전략. \\
  현재 ROVM Server 에서 ArrayRef 가 위치할 수 있는 곳은 아래와 같은 곳들입니다.
  \begin{itemize}
  \item Ticket 구조체의 Stack 슬롯
  \item Ticket 구조체의 Return Stack 슬롯
  \item ObjectRef 의 필드 내부
  \end{itemize}
  위의 해당 항목들을 모두 marking 하는 것입니다.  세번째 항목의 경우,
  Ticket 구조체의 Stack 슬롯들에 대한 타입 검사를 하고 이를 marking
  하게 됩니다.  ArrayRef 의 내부 변수 value 의 경우, 특별하게 취급됩니다.
\item String Reference 에 대한 Garbage Collection 전략. \\
  위의 ObjectRef 와 ArrayRef 와 처리 방식은 동일합니다.  단, StringRef
  의 내부 변수 value 는 특별하게 취급됩니다.
\end{enumerate}

\subsection{Delayed Stack Slot 의 설명}
\label{sec:delayedstackslot}

이 개념은 GC 메모리가 할당된 순간부터 GC thread 에 의해 marking 되는
메모리 공간까지 이동하는 동안 GC thread 에 의해 Garbage 로 인식되어
메모리가 해제되어 버리는 불상사를 막기 위해 도입된 개념입니다.

GC 메모리가 할당되면 항상 자동으로 Delayed Stack Slot 에 들어가게 되어
있습니다.

Delayed Stack Slot 의 초기화는 매번 opcode 의 실행이 끝난 후에
이루어지게 되어 있습니다.  즉, GC 메모리에 대한 할당이 모두 opcode 가
실행되면서 이루어지기 때문에 이런 정책을 펴고 있는 것입니다.

실제 구조는 \$prefix/src/ticket.h 파일에 선언되어 있습니다.

\section{예약 명령어}
\label{sec:reserved}

`예약 명령어' 는 ROVM 서버끼리 서로 원활한 통신을 하기 위해서 예약해
놓은 명령어들로써 이것들을 이용하여 사용자가 디버깅을 할 수 있고, ROVM
서버끼리 통신할 수 있습니다.  또한 명령어들은 실제 VM 실행에 반영되지
않습니다.  실제 VM opcode 들은 \ref{sec:opcodeinst} 장에 자세히
표현되어 있습니다.

아래에서 설명하게 되는 각 항목에 대해 설명을 하면

\begin{description}
\item[번호] `예약 명령어'가 네트워크를 통해서 전해 질 때, 설정되는 번호
  값으로써 1 바이트의 크기를 가지며, 현재 최대 256 개의 `예약 명령어'를
  가질 수 있도록 되어 있습니다.
\item[크기] 명령어가 가질수 있는 크기에 대한 설명입니다.  하지만 많은
  명령어의 경우, 경우에 따라서 가변적인 크기를 가질 수 있으며 이에 대해서는
  해당 명령어의 포맷을 살펴봄으로써 알수 있습니다.
\item[반환값] 명령어를 보냈을 때, 상대측 Client 혹은 Server 에서 응답할
  수 있는 경우들에 대해 나열한 것입니다.
\item[반환값 크기] 반환값의 크기를 의미합니다.
\item[설명] 해당 명령어에 대한 자세한 설명입니다.
\item[예제] 해당 명령어가 네트워크를 통해서 전달될 때의 모습을 표현한 것입니다.
\item[네트워크 상태] 네트워크를 통해서 전달되는 data 의 흐름을 간략하게 표현한 것으로 
  `$\rightarrow$' 는 SEND 를 의미하며, `$\leftarrow$' 는 RECV 를 의미합니다.
\end{description}

\noindent 와 같습니다.

아래에서 설명하는 모든 항목들의 byte order 는 network byte order (big endian) 을 따르게 됩니다.

\pagebreak
\subsection{REQ}
\label{sec:reservedreq}

새로운 Ticket ID 를 요청합니다.  만약 인증 과정이 필요할 경우, 사용자
ID 와 Password 를 담아 보내는 역활을 하게 됩니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 1 (0x1) \\
  \textbf{크기}         & 가변크기 \\
  \textbf{포맷}         & 0x01 \texttt{<auth type>}\\
  \textbf{반환값}       & 다음과 같은 경우의 수가 존재할 수 있습니다.
  \begin{itemize}
  \item \textbf{TICKET} Request ID (유일한 HASH 값)
  \item \textbf{ERROR} ERROR 포맷
  \end{itemize}
  \\
  \textbf{반환값 크기}   & 다음과 같은 경우의 수가 존재할 수 있습니다.
  \begin{itemize}
  \item \textbf{TICKET} 일 경우, 21 bytes
  \item \textbf{ERROR} 일 경우, 해당 포맷에 따라 길이 가변.
  \end{itemize}
  \\
  \textbf{설명}         & Server 측에 request ID 를 요구한다.  이것을 
                           이용하여 client 에서는 모든 정보를 보낼 수 있다. \\
  \textbf{예제}         & REQ \\
  \textbf{네트워크 상태} &
  \begin{itemize}
  \item[] $\rightarrow$ 0x01 0x00
  \item[] $\leftarrow$ 0x04(TICKET) (20 바이트의 Request ID 값)
  \item[] $\leftarrow$ 0x06(ERROR) ...  
  \end{itemize}
  \\
\end{tabular}

`REQ' 명령의 경우, Auth Type 이라는 것이 있습니다.  이것은 세부적인
인증을 선택할 수 있도록 하는 타입으로써 1 바이트 크기를 가집니다.
현재 Auth Type 은 두가지 mode 를 가지고 있습니다.

만약 Auth Type 의 값이 0 일 경우, 이것은 Anonymous 인증을 가르킵니다.
ROVM Server 가 Anonymous 인증을 허락하지 않을 경우, ERROR 가 반환되게
됩니다.

만약 Auth Type 의 값이 1 일 경우, 이것은 사용자 ID/PASSWORD 인증을
가르킵니다.  그래서 REQ 의 포맷이 아래와 같이 구성되게 됩니다.

\begin{verbatim}
0x01 <1 byte auth type> <1 byte userid length> <userid string>
     <1 byte password length> <password string>
\end{verbatim}

\pagebreak
\subsection{REQEND}
\label{sec:reservedreqend}

Ticket ID 를 폐기한다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 2 (0x2) \\
  \textbf{크기}         & 1 바이트 + Ticket ID (20 바이트) \\
  \textbf{포맷}         & 0x02 \texttt{<Ticket ID 20bytes>} \\
  \textbf{반환값}       & \texttt{<OK>} \\
  \textbf{반환값 크기}   & 1 바이트 \\
  \textbf{설명}         & 해당 Request ID 를 이제 client 측에서 더 이상 사용하지 않을 것이기
  때문에 서버에게 지워도 이제 괜찮다는 신호를 전달한다.  이 신호를
  받을 경우, 서버 측에서는 해당 request id 에 대한 모든 자료들을 
  정리한다. \\
  \textbf{예제}         & REQEND \\
  \textbf{네트워크 상태} &
  \begin{itemize}
  \item[] $\rightarrow$ 0x02 \texttt{<Ticket ID 20bytes>}
  \item[] $\leftarrow$ \texttt{<OK>}
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{OPCODE}
\label{sec:reservedopcode}

Opcode 를 실행한다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 3 (0x3) \\
  \textbf{크기}         & 가변 크기 \\
  \textbf{포맷}         & 0x03 \texttt{<TicketID 20bytes>} \texttt{<명령어들 크기 : 4 바이트>} \texttt{<명령어들>} \\
  \textbf{반환값}       & 다음과 같은 경우의 수가 존재할 수 있습니다.
  \begin{itemize}
  \item RETURN
  \item ERROR
  \end{itemize}
  \\
  \textbf{반환값 크기}   &
  \begin{itemize}
  \item RETURN type 에 따라 가변 길이
  \item ERROR 에 따라 가변 길이
  \end{itemize}
  \\
  \textbf{설명}         & 이용 가능한 Ticket ID 를 사용하여, 명령어를 전달한다.  명령어의 길이는
  4 바이트 unsigned int 크기만큼 사용할 수 있다. \\
  \textbf{예제}         &
\begin{verbatim}
OPCODE    <명령어>    <명령어 인자>
OPCODE    new         rovm
OPCODE    pushint     1
\end{verbatim}
  \\
  \textbf{네트워크 상태} &
  \begin{itemize}
  \item[] $\rightarrow$ \texttt{<TicketID 20bytes>} 0x00000008 0x51 weongyo
  \item[] $\leftarrow$ \texttt{<RETURN>} \texttt{<1 바이트 return type>} \texttt{<return type 에 따른 가변길이>}
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{TICKET}
\label{sec:reservedticket}

새롭게 발급된 ticket id 를 전달하기 위한 명령어.  Ticket ID 의 크기는
20 바이트로써 binary 값을 표현합니다.  세부적으로 이야기를 하면 이
해당 바이너리 값은 SHA-1 해쉬값입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 4 (0x4) \\
  \textbf{크기}         & 1 바이트 + Ticket ID (20 바이트) \\
  \textbf{포맷}         & 0x04 \texttt{<Ticket ID 20bytes>} \\
  \textbf{반환값}       & 없음 \\
  \textbf{반환값 크기}   & 없음 \\
  \textbf{설명}         & 클라이언트로부터 Request 가 왔을 경우, valid ticket 이 발행 가능할 
  경우에 이 명령어를 이용하여 반환하여 준다. \\
  \textbf{예제}         & \textbf{TICKET} \texttt{<Valid Ticket ID>} \\
  \textbf{네트워크 상태} &
  \begin{itemize}
  \item[] $\leftarrow$ 0x04 \texttt{<Valid Ticket 20 bytes>}
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{OK}
\label{sec:reservedok}

Client 혹은 Server 의 요청을 성공적으로 받았으며, 그것을 처리하고 있음을
알려주기 위한 명령어
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 5 (0x5) \\
  \textbf{크기}         & 1 바이트 \\
  \textbf{포맷}         & 0x05 \\
  \textbf{반환값}       & 없음 \\
  \textbf{반환값 크기}   & 없음 \\
  \textbf{설명}         & 어떤 예약 명령어에 대해서 return 값이 존재할 필요가 없을 경우에는
                      최소한의 잘 받았다는 메세지로 이 NOP 역활을 하는 메세지를 보내준다.
                      그럼 client 혹은 server 에서는 자신의 메세지가 잘 전달되었다는 것을
                      확인할 수 있기 때문이다. \\
  \textbf{예제}         & \textbf{OK} \\
  \textbf{네트워크 상태} &
  \begin{itemize}
  \item[] $\leftarrow$ 0x05
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{ERROR}
\label{sec:reservederror}

오류 메세지를 전달하는 명령어
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 6 (0x6) \\
  \textbf{크기}         & 1 바이트 + 2 바이트 오류 메세지 수 + [ 1 바이트 오류 level + 2 바이트 문자열 길이 + 문자열 ] \\
  \textbf{포맷}         & 0x06 \texttt{<2 byte total count>} \texttt{<1byte error type>} \texttt{<2bytes string length>} \texttt{<string>} \\
  \textbf{반환값}       & 없음 \\
  \textbf{반환값 크기}   & 없음 \\
  \textbf{설명}         & 만약 실행되는 중간에 오류가 발생하였을 경우, 이 명령어에 자세한 오류 내용을
                          담아 보내게 됩니다. \\
  \textbf{예제}         & \textbf{ERROR} \texttt{<2 바이트 오류 메세지 수>} [\texttt{<1바이트 오류 타입>} 
                         \texttt{<2바이트 문자열 길이>} \texttt{<문자열>}] \\
  \textbf{네트워크 상태} &
  \begin{itemize}
  \item[] $\leftarrow$ 0x06 0x0001 0x01 0x0010 ``Can't find class''
  \end{itemize}
  \\
\end{tabular}

위의 각 항목에 대한 세부 타입은 아래와 같습니다.

\begin{itemize}
\item \emph{2 바이트 오류 메세지 수} \\
  unsigned short
\item \emph{1 바이트 오류 level} \\
  unsigned char
\item \emph{2 바이트 문자열 길이} \\
  unsigned short
\end{itemize}

\textbf{`오류 level' 이란?} \\
단순하게 말해서 오류의 심각도를 말하는 것이다.  INFO, ERROR, CRIT 등등이 존재할 수
있음을 말한다.  현재 오류 타입의 level 은 아래와 같이 정의되어 있습니다.
\bigskip \\
\begin{tabular}[c]{|l|l|l|}
\hline
이름            & Level & 설명 \\
\hline
ERRLOG\_EMERG   & 0     & system is unusable \\
ERRLOG\_ALERT   & 1     & action must be taken immediately \\
ERRLOG\_CRIT    & 2     & critical conditions \\
ERRLOG\_ERR     & 3     & error conditions \\
ERRLOG\_WARNING & 4     & warning conditions \\
ERRLOG\_NOTICE  & 5     & normal but significant condition \\
ERRLOG\_INFO    & 6     & informational \\
ERRLOG\_DEBUG   & 7     & debug-level messages \\
\hline
\end{tabular}

\pagebreak
\subsection{RETURN}
\label{sec:reservedreturn}

Opcode 의 실행에 따른 반환값을 전달하는 명령어입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 7 (0x7) \\
  \textbf{크기}         & 1 바이트 + 1 바이트 type + [ type 에 따라 가변 길이 ] \\
  \textbf{포맷}         & 0x07 \texttt{<type>} \texttt{<content>} \\
  \textbf{반환값}       & 없음 \\
  \textbf{반환값 크기}   & 없음 \\
  \textbf{설명}         & 명령어 OPCODE 가 보내졌을 때, 반환될 수 있는 종류이다.  현재 return type 으로는
  아래와 같은 정이 정해져 있으며, 추후 계속 추가될 수 있다.  단,
  ObjectRef 타입의 경우, 주소가 전달되지 않습니다. \\
  \textbf{예제}         & \textbf{RETURN} \texttt{<1 바이트 type>} \texttt{<type 에 따른 바이트>} \\
  \textbf{네트워크 상태} &
  \begin{itemize}
  \item[] $\leftarrow$ 0x07 0x01 0x00
  \end{itemize}
  \\
\end{tabular}
\bigskip \\
현재 ROVM Server 에 지원하고 있는 각 type 에 따른 이름, Type 번호,
크기에 대한 설명을 한 표가 아래에 있습니다.  아래의 ArrayRef 와
StringRef 를 제외하고는 전송되는 Type 의 byte order 는 little endian
으로 전송됩니다.

\begin{tabular}{|l|l|l|l|}
  \hline
  이름                  & Type 번호     & Type 크기     & C 언어상의 type 과 비교 \\
  \hline
  VOID                 & 0 (0x0)      & 0 바이트        & void \\
  ArrayRef             & 1 (0x1)      & 가변 길이 (아래를 참조) &  \\
  BOOLEAN              & 2 (0x2)      & 1 바이트        & unsigned char \\
  CHAR                 & 3 (0x3)      & 1 바이트        & char \\
  SHORT                & 4 (0x4)      & 2 바이트        & short \\
  INT                  & 5 (0x5)      & 4 바이트        & int \\
  FLOAT                & 6 (0x6)      & 4 바이트        & float \\
  DOUBLE               & 7 (0x7)      & 8 바이트        & double \\
  ObjectRef            & 8 (0x8)      & 0 바이트        & void * \\
  StringRef            & 9 (0x9)      & 가변 길이 (아래를 참조) &  \\
  \hline
\end{tabular}

ArrayRef 의 경우, 다른 type 들과 달리, 가변 길이를 가지고 있습니다.
상세 타입은 아래와 같습니다.

\begin{verbatim}
RETURN <ArrayRef_TYPE> <4 byte arrlen> [ <1bytetype> <typecontent> [ ... ] ]
\end{verbatim}

각 항목에 대한 설명을 한다면

\begin{itemize}
\item \emph{4 byte arrlen} \\
  현재 ArrayRef 상에서의 배열의 총 갯수입니다.
\item \emph{1bytetype} \\
  현재 항목의 Type 을 가르킵니다.  이 Type 은 각 항목마다 존재할 수
  있으며, 위의 표에 나와 있는 `Type 번호' 를 가르킵니다.  즉, ArrayRef
  의 경우, Type 에 의존적이지 않기 때문에, 배열내에 여러 type 의
  값들이 서로 존재할 수 있습니다.
\item \emph{typecontent} \\
  각 Type 의 바이트 크기를 가지고 있습니다.  위의 표 중 `Type 크기'에
  해당하는 값을 가르킵니다.
\end{itemize}

StringRef 의 경우, 또한 가변 길이를 가지고 있으며, 상세 타입은 아래와
같습니다.

\begin{verbatim}
RETURN StringRef <4 byte string length> <strings>
\end{verbatim}

4 바이트 크기의 문자열 길이가 먼저 온 후, 뒤에 해당 문자열 크기만큼
바이트가 전송되게 됩니다.

예를 들어 설명한다면

\begin{verbatim}
arrayref ([(int 4)
           (stringref "Hello World!")
           (float 1.0)])
\end{verbatim}

위와 같은 반환값이 온다면, 해당 바이트는 아래와 같은 값을 가질
것입니다.

\begin{verbatim}
0x07                    (RETURN)
0x01                    (ArrayRef Type)
0x00 0x00 0x00 0x03     (ArrayLen : Network endian)
0x05                    (INT)
0x04 0x00 0x00 0x00     (INT value : little endian)
0x09                    (StringRef)
0x00 0x00 0x00 0x0c     (String Length)
Hello World!
0x06
<4 byte : float data>
\end{verbatim}

\emph{(아직 `RETURN' 명령어의 경우, 계속 개발 중에 있는 항목입니다.  이에
대한 정보는 지속적으로 업데이트가 될 것입니다.)}

\pagebreak
\subsection{GETSTACK}
\label{sec:reservedgetstack}

Ticket ID 의 현재 stack 상태를 받아옵니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 8 (0x8) \\
  \textbf{크기}         & 1 바이트 + 20 바이트 TICKET ID \\
  \textbf{포맷}         & 0x08 \texttt{<Ticket ID>} \\
  \textbf{반환값}       & \textbf{ERROR} \\
  \textbf{반환값 크기}   & \textbf{ERROR} 의 경우, 가변 길이 \\
  \textbf{설명}         & 
  TICKET ID 의 현재 스택 상태를 받아와 출력한다.  이것의 리턴값은 \textbf{ERROR} 로써
  ERROR 의 오류 타입은 ERRLOG\_DEBUG 로 설정되어 있다.
  
  이 명령어는 Debugging 용으로써 기본적인 설치시 disable 되어 있을 것이다. \\
  \textbf{예제}         & \textbf{GETSTACK} \texttt{<20 바이트 TICKET ID>} \\
  \textbf{네트워크 상태} &
  \begin{itemize}
  \item[] $\rightarrow$ 0x08 \texttt{<20 바이트 TICKET ID>}
  \item[] $\leftarrow$ 0x07 0x01 0x00
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\section{opcode  명령어}
\label{sec:opcodeinst}

이 절에서는 ROVM 에서 실제로 사용하는 opcode 들에 대한 모든 설명을 하겠습니다.
opcode 는 1 바이트 크기로 총 256 개의 ROVM 명령어가 존재합니다.  모든 명령어가
현재 정해져 있는 것은 아니며, 정렬 순서는 `\textbf{번호}' 순으로 나열되어 있습니다.

각각에 대한 항목을 설명하면 아래와 같습니다.

\begin{description}
\item[번호] Opcode 번호
\item[형식] Opcode 의 고유 format 을 가르킵니다.
\item[스택] Opcode 가 실행되었을 때, 스택의 변화를 기록한 항목입니다.  `$\rightarrow$' 를
  기준으로 왼쪽은 `이전 스택 상태'이며, 오른쪽은 `이후 스택 상태'입니다.
\item[예제] 이 항목은 ROVM Client 를 사용하여 실제로 코드를 작성할 때 사용할 수
  있는 형식을 가르킵니다.
\end{description}

\pagebreak
\subsection{NOP}
\label{sec:opnop}

아무일도 하지 않습니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 0 (0x0) \\
  \textbf{형식}         & NOP \\
  \textbf{스택}         & (...) $\rightarrow$ (...) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] nop
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{BPUSH}
\label{sec:opbpush}

Boolean 을 PUSH 합니다.  값이 1 일 경우는 TRUE 를 의미하고, 0 일
경우는 FALSE 를 의미합니다.  그 외의 값은 오류입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 13 (0xd) \\
  \textbf{형식}         & dpush \texttt{<1 byte unsigned char>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{<boolean>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] bpush 1
  \item[...] bpush 0
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{FPUSH}
\label{sec:opfpush}

Float 을 PUSH 합니다.  이 타입은 C 언어의 `float' 와 동일합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 14 (0xe) \\
  \textbf{형식}         & fpush \texttt{<4 byte float>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{<float>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] fpush 1.0
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{DPUSH}
\label{sec:opdpush}

Double 을 PUSH 합니다.  이 타입은 C 언어의 `double 와 동일합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 15 (0xf) \\
  \textbf{형식}         & dpush \texttt{<8 byte double>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{<double>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] double 1.0
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{CPUSH}
\label{sec:opcpush}

Char 을 PUSH 합니다.  Char 은 1 바이트의 type 으로써 C 언어의
`char' 와 완벽하게 같습니다.  숫자의 범위 -128 ~ 127 까지 입니다.
더하기 등등의 연산시 이 값은 integer 로써 계산이 되게 됩니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 16 (0x10) \\
  \textbf{형식}         & cpush \texttt{<1 byte number>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{<char number>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] cpush -128
  \item[...] cpush 127
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{HPUSH}
\label{sec:ophpush}

Short 을 PUSH 합니다.  이 타입은 C 언어의 `short 와 동일합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 17 (0x11) \\
  \textbf{형식}         & hpush \texttt{<2 byte short>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{<short>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] short 234
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{IPUSH}
\label{sec:opipush}

Integer 을 PUSH 합니다.  Integer 은 4 바이트의 type 으로써 C 언어의
`int 와 완벽하게 같습니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 18 (0x12) \\
  \textbf{형식}         & ipush \texttt{<4 byte signed number>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{<int number>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] ipush -2147483648
  \item[...] ipush 2147483647
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{SPUSH}
\label{sec:opspush}

문자열을 stack 상에 PUSH 합니다.  PUSH 된 문자열은 자동으로 StringRef
(ObjectRef 의 다른 이름으로써, 문자열과 관련된 점만 강조하기 위해서
지은 이름입니다.) 로 변환되게 되어 저장되게 됩니다.  가변길이를 가지는
opcode 입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 19 (0x13) \\
  \textbf{형식}         & spush \texttt{<4 byte unsigned string
    length> <string>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{\emph{<StringRef>}}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] spush ``Hello! ROVM Server''
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{ILOAD}
\label{sec:opiload}

Local 변수의 설정되어 있는 값을 stack 에 push 하는 역활을 하는 opcode
입니다.  Local 변수를 지정하기 위한 index 값은 1 바이트 크기로써 최대
256 개 변수를 지정할 수 있습니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 21 (0x15) \\
  \textbf{형식}         & iload \texttt{<1 byte unsigned local idx>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{<value>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] iload 0
  \item[...] iload 255
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{POP}
\label{sec:oppop}

Stack 의 가장 위에 있는 항목을 POP 합니다.
\bigskip \\
\begin{tabular}{r|p{12cm}}
  \textbf{번호}         & 87 (0x57) \\
  \textbf{형식}         & pop \\
  \textbf{스택}         & (..., \texttt{<value>}) $\rightarrow$ (...) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] pop
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{DUP}
\label{sec:opdup}

Stack 의 가장 위에 있는 항목을 그대로 복사하여 하나 더 PUSH 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 89 (0x59) \\
  \textbf{형식}         & dup \\
  \textbf{스택}         & (..., \texttt{<value>}) $\rightarrow$ (..., \texttt{<value>}, \texttt{<value>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] dup
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{SWAP}
\label{sec:opswap}

Stack 의 가장 위에 있는 두개의 항목 위치를 서로 바꿉니다.
\bigskip \\
\begin{tabular}{r|p{12cm}}
  \textbf{번호}         & 95 (0x5F) \\
  \textbf{형식}         & swap \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<value2>}, \texttt{<value1>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] swap
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{IADD}
\label{sec:opiadd}

스택에서 2 개의 integer entry 를 pop 한 후에, 더하고 그에 대한 결과를 다시
push 합니다.

\emph{Result} 의 Stack Type 은 \emph{value1} 혹은 \emph{value2} 에 상관없이
Integer Type 이 됩니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 96 (0x60) \\
  \textbf{형식}         & iadd \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] ipush 1
  \item[...] ipush 2
  \item[...] iadd
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{FADD}
\label{sec:opfadd}

스택에서 2 개의 float entry 를 pop 한 후에, 더하고 그에 대한 결과를 다시
push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 98 (0x62) \\
  \textbf{형식}         & fadd \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] fpush 1.0
  \item[...] fpush 2.0
  \item[...] fadd
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{DADD}
\label{sec:opdadd}

스택에서 2 개의 double entry 를 pop 한 후에, 더하고 그에 대한 결과를 다시
push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 99 (0x63) \\
  \textbf{형식}         & dadd \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] dpush 1123.0
  \item[...] dpush 2321.0
  \item[...] dadd
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{ISUB}
\label{sec:opisub}

스택에서 2 개의 double entry 를 pop 한 후에, 두 값을 뺀 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 100 (0x64) \\
  \textbf{형식}         & isub \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] ipush 1
  \item[...] ipush 2
  \item[...] isub
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{FSUB}
\label{sec:opfsub}

스택에서 2 개의 float entry 를 pop 한 후에, 두 값을 뺀 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 102 (0x66) \\
  \textbf{형식}         & fsub \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] fpush 1.0
  \item[...] fpush 2.0
  \item[...] fsub
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{DSUB}
\label{sec:opdsub}

스택에서 2 개의 double entry 를 pop 한 후에, 두 값을 뺀 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 103 (0x67) \\
  \textbf{형식}         & dsub \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] dpush 5.0
  \item[...] dpush 2.0
  \item[...] dsub
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{IMUL}
\label{sec:opimul}

스택에서 2 개의 integer entry 를 pop 한 후에, 두 값을 곱한 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 104 (0x68) \\
  \textbf{형식}         & imul \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] ipush 1
  \item[...] ipush 2
  \item[...] imul
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{FMUL}
\label{sec:opfmul}

스택에서 2 개의 float entry 를 pop 한 후에, 두 값을 곱한 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 106 (0x6a) \\
  \textbf{형식}         & fmul \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] fpush 1.0
  \item[...] fpush 2.0
  \item[...] fmul
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{DMUL}
\label{sec:opdmul}

스택에서 2 개의 double entry 를 pop 한 후에, 두 값을 곱한 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 107 (0x6b) \\
  \textbf{형식}         & dmul \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] dpush 1123.0
  \item[...] dpush 212.0
  \item[...] dmul
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{IDIV}
\label{sec:opidiv}

스택에서 2 개의 integer entry 를 pop 한 후에, 두 값을 나눈 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 108 (0x6c) \\
  \textbf{형식}         & idiv \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] ipush 10
  \item[...] ipush 2
  \item[...] idiv
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{FDIV}
\label{sec:opfdiv}

스택에서 2 개의 float entry 를 pop 한 후에, 두 값을 나눈 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 110 (0x6e) \\
  \textbf{형식}         & fdiv \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] fpush 10.0
  \item[...] fpush 2.0
  \item[...] fdiv
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{DDIV}
\label{sec:opddiv}

스택에서 2 개의 double entry 를 pop 한 후에, 두 값을 나눈 결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 111 (0x6f) \\
  \textbf{형식}         & ddiv \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] dpush 10.0
  \item[...] dpush 2.0
  \item[...] ddiv
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{IREM}
\label{sec:opirem}

스택에서 2 개의 integer entry 를 pop 한 후에, 두 값을 나눈 나머지
결과를 다시 push 합니다.  C 언어에서 \% 연산자와 의미가 같습니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 112 (0x70) \\
  \textbf{형식}         & irem \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] ipush 3
  \item[...] ipush 2
  \item[...] irem
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{FREM}
\label{sec:opfrem}

스택에서 2 개의 float entry 를 pop 한 후에, 두 값을 나눈 나머지
결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 114 (0x72) \\
  \textbf{형식}         & frem \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] fpush 3.0
  \item[...] fpush 2.0
  \item[...] frem
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{DREM}
\label{sec:opdrem}

스택에서 2 개의 double entry 를 pop 한 후에, 두 값을 나눈 나머지
결과를 다시 push 합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 115 (0x73) \\
  \textbf{형식}         & drem \\
  \textbf{스택}         & (..., \texttt{<value1>}, \texttt{<value2>}) $\rightarrow$ (..., \texttt{<result>}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] dpush 33.0
  \item[...] dpush 22.0
  \item[...] drem
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{IRETURN}
\label{sec:opireturn}

Method 의 리턴값 integer 를 반환하고, method 실행을 끝내는 명령어
입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 172 (0xac) \\
  \textbf{형식}         & ireturn \\
  \textbf{스택}         & (..., \texttt{<value>}) $\rightarrow$ \emph{empty} \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] ireturn
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{FRETURN}
\label{sec:opfreturn}

Method 의 리턴값 float 를 반환하고, method 실행을 끝내는 명령어
입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 174 (0xae) \\
  \textbf{형식}         & freturn \\
  \textbf{스택}         & (..., \texttt{<float value>}) $\rightarrow$ \emph{empty} \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] freturn
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{DRETURN}
\label{sec:opdreturn}

Method 의 리턴값 double 를 반환하고, method 실행을 끝내는 명령어
입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 175 (0xaf) \\
  \textbf{형식}         & dreturn \\
  \textbf{스택}         & (..., \texttt{<double value>}) $\rightarrow$ \emph{empty} \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] dreturn
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{ARETURN}
\label{sec:opareturn}

Method 의 리턴값 Reference 를 반환하고, method 실행을 끝내는 명령어
입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 176 (0xb0) \\
  \textbf{형식}         & areturn \\
  \textbf{스택}         & (..., \texttt{<Reference>}) $\rightarrow$ \emph{empty} \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] areturn
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{RETURN}
\label{sec:opreturn}

Method 의 리턴값 VOID 를 반환하고, method 실행을 끝내는 명령어
입니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 177 (0xb1) \\
  \textbf{형식}         & return \\
  \textbf{스택}         & (...) $\rightarrow$ \emph{empty} \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] areturn
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{CALL}
\label{sec:opcall}

Class 에 선언된 method 를 호출할 때 사용되는 명령어입니다.  이
명령어가 잘 작동하기 위해서는 반드시 스택상에 \emph{objectref} 가
존재해야 하며, 만약 argument 를 넘겨줄 필요가 있을 경우, 해당 argument
를 스택에 알맞게 쌓아 놓아야 합니다..  
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 182 (0xb6) \\
  \textbf{형식}         & call \texttt{<name>} \texttt{<type>} \\
  \textbf{바이트형식}    & \texttt{<opcode> <1 byte name length>
    <name string> <2 byte type length> <type string>} \\
  \textbf{스택}         & (..., \emph{\texttt{<objectref>}}, [\emph{arg1}, [\emph{arg2} ...]]) $\rightarrow$ (...) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] call __init__ (S)V
  \item[...] call abc (SII)I
  \end{itemize}
  \\
\end{tabular}

만약 CALL 이 호출된 후, 메쏘드가 리턴값을 가지고 있을 경우를
생각해줘야 하는데, 위의 스택의 모형의 경우, 함수 호출이 끝난 후
리턴값이 스택에 설정되지 않는 것처럼 나와 있지만 내부 동작은 조금
다릅니다.

리턴 타입이 어떤 것이냐에 따라서 조금씩 스택 모형이 변동이 됩니다.  예를
들면 리턴 타입이 'V' 일 경우, call 호출 후에 리턴값이 PUSH 되지
않습니다.

그 외의 리턴 타입일 경우, 스택상에 해당 값이 PUSH 되게 됩니다.

\pagebreak
\subsection{NEW}
\label{sec:opnew}

지정한 Class 에 대한 Object Reference 를 PUSH 합니다.

지정한 Class 에 대한 Object Reference 를 구해서 Stack 에 PUSH 하게
됩니다.  만약 해당 Class 를 찾지 못하였거나, 성공적으로 Load 하지
못하였거나, 해당 Object Reference 를 생성하지 못하였다면, `ERROR' 메세지를
반환하게 됩니다.

아래 항목 중 `바이트 형식'에 대해서는 좀 더 자세한 설명이 필요할 듯 합니다.
\begin{itemize}
\item Opcode \\
  보통의 opcode 입니다.  1 바이트
\item Type (1 바이트) \\
  이 부분은 다음에 나올 \texttt{<hostname>} 의 형식이 IPv4 형식인지 IPv6 형식인지를 
  결정할 수 있도록 도와주는 flag 입니다.

  만약 값이 0x00 일 경우는 IPv4 를 의미하며, 0x01 일 경우는 IPv6 값을 의미합니다.

  \emph{주의) 현재 공식적으로 IPv6 를 지원하지는 않습니다.}
\item HostName Length (2 바이트) \\
  다음으로 나올 `hostname' 의 길이를 가르킵니다.
\item Hostname String \\
  문자열로 구성된 hostname 입니다.
\item Port (2 바이트) \\
  `unsigned short' 타입은 2 바이트 포트 번호입니다.  만약 값이 0x0000
  일 경우, ROVM Server 의 default port (4390) 을 사용하게 됩니다.
\item Path Length (2 바이트) \\
  로드할 Class 파일의 위치 정보 중 하나로 경로의 길이를 가르킵니다.
  `unsigned short' 타입입니다.
\item Path String \\
  로드할 Class 파일의 위치
\end{itemize}

\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 187 (0xbb) \\
  \textbf{형식}         & new \texttt{e://<hostname>[:<port>]<path>} \\
  \textbf{바이트형식}    & \texttt{<opcode> <type>
    <hostname length> <hostname string> 
    <2 byte port>
    <2 byte path length> <path string>} \\
  \textbf{스택}         & (...) $\rightarrow$ (..., \texttt{\emph{<objectref>}}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] \texttt{new e://192.168.58.129:4390/testsuite/insert}
  \item[...] \texttt{new e://envlang.kldp.net/testsuite/insert}
  \end{itemize}
  \\
\end{tabular}

\pagebreak
\subsection{NEWARRAY}
\label{sec:opnewarray}

배열을 생성하는 opcode 입니다.  \emph{n} 개의 배열을 만들기 위해서는
이 명령어가 실행되기 전에 해당 정보를 스택에 PUSH 해 놓아야 합니다.
해당 정보를 바탕으로 배열을 생성하여 그에 맞는 ArrayRef 를 반환하게
됩니다. 

구지 갯수 \emph{n} 을 정확하게 할 필요는 없으며, 배열의 길이는
언제든이 증가 가능합니다.  보통 0 개에서 시작하여 배열 객체의 메쏘드를
이용하여 추가하는 것이 보통입니다.

배열 객체는 Type 정보를 가지고 있지 않습니다.  이말은 배열내에서는
어떤한 Type 의 정보들이 모두 한 배열 속에 존재할 수 있다는 말을
의미합니다.
\bigskip \\
\begin{tabular}{r|p{8.5cm}}
  \textbf{번호}         & 188 (0xbc) \\
  \textbf{형식}         & newarray \\
  \textbf{스택}         & (..., \emph{\texttt{<count>}}) $\rightarrow$
  (..., \emph{\texttt{<arrayref>}}) \\
  \textbf{예제}         &
  \begin{itemize}
  \item[...] ipush 0
  \item[...] newarray
  \end{itemize}
  \\
\end{tabular}

\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 
