본문 바로가기
개발(Development)/JS(자바스크립트)

자바스크립트 코드 실행 동작 원리: 엔진, 가상머신, 인터프리터, AST 기초

by 카레유 2021. 3. 12.

웹개발자라면, 적든 많든 자바스크립트를 다루지 않을 수 없습니다.

이번 글에서는 자바스크립트 코드가 내부적으로 어떤 원리로 실행되는지를 정리해 보려고 합니다.

 

아래 그림은 자바스크립트의 구동원리를 도식화한 것입니다.

 

이 글을 끝까지 읽으시면, 이 그림이 완벽히 이해되실겁니다.


# 자바스크립트 코드의 구동 원리

일반적으로 소스코드는 어떤 원리로 실행될까요?

1.  코드 실행의 기본 원리

-  프로그래밍 언어로 코드를 작성한다.

-  인터프리팅, 컴파일 등의 과정을 통해 0, 1로 이루어진 기계어로 변환된다.

-  0, 1로 이루어진 기계어 코드가 '메모리'라는 곳에 저장된다.

- CPU는 메모리에 있는 0, 1로 이루어진 코드를 읽어 on/off 전기 신호로 실행시킨다.

* on/off 전기신호는 이진수 계산으로 각종 연산을 수행하며, 사실 메모리에 저장된 데이터도 전기신호입니다.

 

 

프로그래밍 코드, 기계어는 어떻게 다를까요?

2. 언어의 종류

1) 고급언어

- 자바스크립트나 Java처럼 사람이 이해하고 작성하기 쉬운 코드.

- 인터프리팅, 컴파일 등을 통해 최종적으로 기계어로 변환되어 CPU에서 실행된다.

const num = 10;
const add = num + 20;
console.log(add);

 

2) 바이트코드(Bytecode)

- 사람이 작성한 고급언어(Javascript등)를 가상머신이 이해할 수 있도록 변환한 코드.

- 가상머신은 바이트코드를 다양한 종류의 CPU에 맞게 기계어로 컴파일 한다.

Add r0, [6] LdaSmi [1]

 

3) 기계어(Machine Code)

- CPU가 바로 읽어서 실행할 수 있는 비트 단위의 이진 코드(0, 1).

- CPU 종류에 따라 코드를 해독하고 수행하는 방식이 다르며, 어셈블리어와 1대 1로 대응 된다.

10110000 01100001

 

참고) 어셈블리어(assembly language)

- 기계어로 구성된 명령어를 사람이 알아보기 쉬운 니모닉 기호(mnemonic symbol)를 정해 

사람이 좀 더 쉽게 컴퓨터의 행동을 제어할 수 있도록 한 것으로 기계어보다 한 단계 위의 저급언어이다.

mov al, 061h

 

 

고급언어는 어떤 방식으로 기계어로 변환될까요?

3. 코드 해석/변환 방식

: 고급언어로 작성된 코드는 컴파일러, 인터프리터를 통해 CPU가 실행할 수 있도록 변환된다.

1) 컴파일러(Compiler)

: 파일 전체를 읽은 뒤, 코드의 의미를 해석하고 파일 전체를 기계어로 변환한다.(이 과정을 '컴파일'이라고 한다)

 

2) 인터프리터(Interpreter)

: 코드를 한 줄 한 줄 읽어내려가며 한 줄씩 중간 단계의 Bytecode로 변환한다.(이 과정을 '인터프리팅'이라고 한다)

* 자바스크립트는 기본적으로 인터프리터 언어이다.

 

 

그럼, 자바스크립트 코드는 구체적으로 어떻게 기계어로 변환되어 실행될까요?

4. 자바스크립트 구동원리

: 자바스크립트 코드 > Byte code > 기계어 > CPU 코드 실행

자바스크립트 코드 실행 원리

1) 자바스크립트 코드 작성

- 개발자가 자바스크립트 코드를 작성한다.

 

2) Byte code 변환

- 자바스크립트 엔진은 코드를 위에서부터 줄씩 해석하면서(인터프리터 언어) 가상머신이 이해할수 있는 Byte code 변환한다.

 

3) 기계어 변환

- 가상머신은 Byte code CPU 이해할 있는 기계어로 변환한다.

- 단, CPU마다 기계어를 다르게 해석하므로 가상 머신은 CPU별로 최적화된 기계어를 만들어 낸다.

- 따라서 개발자는 CPU마다 다른 자바스크립트 코드를 작성할 필요가 없다.(하나의 자바스크립트 코드만 작성하면 된다.)

 

4) CPU 코드 실행

- 컴퓨터의 CPU는 가상머신이 만들어낸 기계어를 수행한다.

- 기계어(전기신호)대로 메모리에 데이터를 저장하고, 읽고, 연산하고, 출력하는 작업 등을 수행한다.

 

 

 그런데, 자바스크립트 엔진은 어떤 방식으로 "자바스크립트 코드"를 "바이트 코드"로 변환하는 걸까요?

5. 자바스크립트 엔진 구조

: 자바스크립트 코드 > 토큰(Token) > AST(추상구문트리) >  바이트코드 변환

자바스크립트 엔진 구조 및 원리

1) 토크나이저(Tokenizer)

- 자바스크립트 코드를 분석하여 '의미를 갖는 최소 단위'인 토큰(Token)으로 분해합니다.

- 이 과정을 토크나이징(Tokenizing)이라고 부릅니다

 

2) 파서(Parser)

- 분해한 '토큰'들을 분석하여, 문법적으로 의미를 갖는 Tree 자료구조(AST: Abstract Syntax Tree)를 만듭니다

- 이 과정을 파싱(Parsing)이라고 부릅니다.

 

3) 인터프리터(Interpreter)

- 파싱된 결과물인 AST를 byte code로 변환합니다.


여기까지 자바스크립트의 구동 원리를 간단하게 정리해보았습니다.

 

위 내용은 아주아주 단순화해서 정리한 것입니다.

 

실제로 자바스크립트가 구동되는 환경(브라우저, node 등)의 자바스크립트 엔진(V8 등)은

인터프리터 방식과 컴파일 방식을 함께 사용하여 최적화된 성능을 구현하며, 엔진마다 세부 사항이 다릅니다.

엔진별로 더욱 상세한 내용은 각 엔진의 명세서를 참고하시기 바랍니다.

 

참고) 자바스크립트 엔진 종류

- V8: Google Chrome, Node.js, Electron 등 에서 사용

- Javascript Core: Apple Safari 등에서 사용

- SpiderMoneky: Mozilla FireFox 등에서 사용

- Chakra: Microsoft Edge 등에서 사용

 

 

도움이 되셨길 바라겠습니다.

 

 

댓글