[javascript] 자바스크립트 엔진 정리

자바스크립트 엔진

결론부터 말하자면, 자바스크립트 엔진은 자바스크립트로 작성한 코드를 해석하고 실행시켜 주는 인터프리터이다.
인터프리터에 대해 더 자세히 알아보기 전 인터프리터를 비롯한 언어의 인터프리팅 전반에 대해 짚고 넘어가자.

기계어와 어셈블리어

기본적으로 컴퓨터에게 어떠한 명령을 실행하기 위해서는 CPU가 알아들을 수 있는 기계어 를 사용해야 한다.
CPU가 직접 해독하고 실행할 수 있는 비트 단위로 쓰인 컴퓨터 언어를 기계어라고 한다. 기계어는 우리가 흔히 알고 있는 0과 1로 이뤄진 비트로 구성되어 있다.

< 기계어의 모습 >
001001 11101 11101 1111111111111000
001000 00001 00000 0000000000001010
001000 00001 00001 0000000000000010
101011 11101 00001 0000000000000000
001000 00010 00001 0000000000000100
101011 11101 00010 0000000000000100
001001 11101 11101 0000000000001000

하지만 현실적으로 사람이 기계어를 직접 작성하여 명령을 내리는 것은 많은 어려움이 따른다. 따라서 이러한 불편함을 해소하고자 하는 해결책의 첫 걸음으로 어셈블리어 가 개발되었다. 어셈블리어는 기계어 명령에 1대1로 대응하는 니모닉 기호로 구성되어 있다.

< 기계어 >
10110000 01100001

< 위의 기계어를 어셈블리어로 변환 >
mov al, 016h //  al 이라는 레지스터에 016h 값을 옮기겠다(move)는 뜻

기계어를 좀 더 인간이 편하게 작성하기 위해 만들어진 어셈블리어지만, 이 어셈블리어는 어쨌든 기계어가 아니기 때문에 CPU가 이해할 수 없어 어셈블리어를 기계어로 변환 해주는 작업이 필요하다. 이 역할을 해주는 프로그램이 어셈블러 이다.

기계어나 어셈블리어처럼 컴퓨터 내부에서 바로 처리 가능한 언어를 저급 프로그래밍 언어(Low-level programming language) 라고 한다. 여기에서 이야기하는 “저급”은 프로그램의 질적인 수준을 뜻하는 것이 아니라 문법의 추상화 수준이 기계어에 가깝다는 의미다.

이러한 저급 프로그래밍 언어는 아주 강력하고 빠르지만, 인간이 너무 상세한 부분까지 책임져야해서 사용하기가 어렵다. 게다가 어셈블리어의 경우 컴퓨터 구조에 따라 사용하는 기계어가 달라지다보니, 기계어에 대응하는 어셈블리어도 각각 달라져야한다. 서로 다른 CPU 아키텍처가 등장하면 매번 똑같은 프로그램을 다른 어셈블리어로 작성하는 비용도 발생한다.

그래서 인간이 이해하기 쉽고 어떤 CPU에서도 동작 가능한 새로운 패러다임의 프로그래밍 언어가 필요하게 되었다.

컴파일러와 인터프리터

시간이 지남에 따라 사람들이 조금 더 편하게 쓸 수 있는 고급 프로그래밍 언어(High-level programming language) 이 만들어졌다. 대표적으로 C,C++,Java 등 현재 우리가 흔히 배울 수 있는 언어들이 그렇다.

고급 프로그래밍 언어를 저급 프로그래밍 언어로 변환하는 방법에는 크게 컴파일러 방식과 인터프리터 두 가지가 있다.

컴파일러

특정 언어로 작성한 코드를 다른 언어로 변환하는 프로그램을 말한다.
대표적인 언어로 C,C++이 있으며, 주로 원시코드(본래 작성한 코드)를 어셈블리어나 기계어로 변환한다. 직접 기계어를 생성하면 부담이 크기 때문에 어셈블러 형식의 목적 파일로 생성하는 경우가 많다.

컴파일러는 원시코드 파일을 변환하는 과정을 거쳐 어셈블러 형식의 목적 프로그램을 만들고, 이를 실행하는 명령을 지시함으로써 실제 프로그램을 실행한다.

인터프리터

이에 반해 인터프리터는 소스를 컴파일하여 목적 프로그램으로 만들지 않고, 코드의 라인 단위로 해석하며 바로 실행한다.
별도의 컴파일 과정이 없어 바로 실행할 수 있지만 한 줄 한 줄 인터프리팅 과정을 갖기 때문에 속도가 조금 느리다.

인터프리터에는 크게 두 가지 종류가 있는데, 첫 번째는 “인터프리터와 컴파일러의 결합형” 이다.
이는 컴파일러와 인터프리터의 절충안으로, 원시코드를 기계어가 아닌 중간즈음의 형태(JAVA의 경우 bytecode)로 변환한 후(컴파일러 과정), 이 변환한 코드를 인터프리터가 읽어들여 메모리에 적재 후 한줄 한줄 해석하며 실행한다.(인터프리터 과정)
이러한 인터프리터를 사용하는 언어는 대표적으로 JAVA 가 있다.

두 번째 종류로는 “소스 코드 유지형” 이 있다.
소스 코드를 유지한다고 해서 아무런 변환도 하지 않는 것은 아니다. 성능 향상을 위해서 실행 시점에 원시 코드나 중간 코드를 네이티브 코드로 변환하는데 이러한 기법을 JIT Compile 이라고 한다.
JIT(Just-in-time) Compiler는 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일러이며, JavaScript Engine이 이러한 유형의 인터프리터다. 좀 전에 언급한 Java의 경우도 이러한 JIT Compile 기법(bytecode -> 기계어)을 적용하고 있다.

자바스크립트 엔진

자바스크립트 엔진은 자바스크립트 코드를 해석하고 실행하는 인터프리터를 말한다.
시작은 웹브라우저에서부터였지만, 현재는 자바스크립트 엔진을 통해 서버를 만들 수도 있는 등 브라우저 밖으로 꾸준히 나오고 있는 추세이다.

대표적으로 Mozilla의 SpiderMonkey(파이어폭스), 구글의 V8(크롬/오페라/Node.js), 사파리의 니트로, IE의 Chakra 등이 있다.

http://huns.me/wp/wp-content/uploads/2013/09/SpiderMonkey.png

참고로 Node.js는 Chrome V8 Javascript 엔진으로 빌드된 Javascript 런타임이다. 런타임이란 프로그래밍 언어가 실행되는 환경을 뜻한다.

참고 URL

Interpreter and JavaScript Engine
Node.js란…?