자바스크립트 엔진은 인터프리터라구요? 컴파일도 하는데요...
자바스크립트를 다시 공부하면서 구동 원리를 정리해봅니다.
자바스크립트는 이렇게 동작해요.

(출처: https://curryyou.tistory.com/237 )
1. 자바스크립트 입력
- 고급 언어인 자바스크립트 코드가 엔진에 의해 처리되기 시작합니다.
- 궁극적으로는 기계어로 변환되어야 합니다. 컴퓨터가 이해할 수 있어야 하니까요.
2. 토크나이징
- 고급 언어를 받아 토큰으로 토크나이징을 시작합니다.
- 이때 토큰은 의미를 가진 최소 단위입니다.
- 이러한 오브젝트 형식을 떠올리면 좋을 것 같아요.
/* 놀랍게도 let이었던 것 */
{
type: "keyword",
value: let
}
/* 놀랍게도 value였던 것 */
{
type: "name",
value: num
}
/* 놀랍게도 = 였던 것 */
{
type: "=",
value: "="
}
3. 파싱
-
토큰을 분석하여 문법적으로 의미를 갖는 트리 구조 형태로 만듭니다.
-
이를 AST라고 합니다!
-
이때 트리의 각 노드는 소스코드에서 발생되는 어떤 구조들을 의미합니다.
-
[위키백과] 에서는 컴파일의 한 단계로서 파싱을 명시하고 있는데요, 자바스크립트에서의 파싱은 컴파일 단계가 아닌 인터프리팅의 전 단계에서 발생한다고 볼 수 있을 것 같아요. ( 위키백과의 컴파일
은 다소 거시적인 차원의 컴파일
을 말하는 것 같아요. )
-
요랬던 코드가...

-
요렇게 바뀝니다.

-
https://astexplorer.net/ 에서 추상문법트리의 파싱 결과물을 확인할 수 있더라구요!
4. 인터프리팅
- AST를 바이트 코드로 변환합니다.
- 자바스크립트는 소스코드의 한줄 한줄을 읽고 인터프리팅합니다 -> 과연??!
5. 기계어 변환
- 가상머신은 바이트 코드를 CPU가 이해할 수 있는 기계어로 변환합니다.
- 가상머신은 CPU별로 최적화된 기계어를 만들어냅니다.
- 변환된 기계어는 이제 컴퓨터가 소화할 수 있어요.
아니 컴파일을 안하는데요?
토크나이징 -> 파싱 -> 인터프리팅 -> 기계어 변환 과정에서 컴파일이 없는데요?
자바스크립트는 파싱을 끝내고 결과로 도출된 AST를 인터프리팅하려 합니다. 이때, 인터프리터에 전달되는 AST는 컴파일 후보가 됩니다.
🔥 V8엔진의 이야기 : 인터프리팅을 감시하는 Profiler 🔥

- 오늘도 V8은 인터프리팅을 시작합니다.
- 끊임없이 밀려들어오는 코드에 V8은 환멸을 느낍니다.
- console.log()는 왜이리 많이 호출하는 것인지, 소스코드에서 사용될 때마다 console.log()를 읽고 처리하는데 지쳐버렸습니다.
- 지쳐버린 V8은 옆자리에 있던 Profiler를 시켜 console.log()를 미리 실시간으로 "컴파일"해놓도록 부탁합니다.
- Profiler는 반복되는 console.log()를 실시간으로 컴파일하고 V8에게 넘깁니다. V8은 이제 AST의 각 노드를 읽고 처리(인터프리팅)할 필요가 없습니다.
- V8은 이제 행복합니다.
그래서 결론은?
- 자바스크립트의 컴파일러는 "필요한 경우"에만 컴파일을 하는 JIT컴파일러(just-in-time)라고 할 수 있습니다.
- 필요한 경우라고 한다면 반복적으로 호출되는 함수를 예로 들 수 있겠습니다.
- decompile하는 경우도 있습니다. Profiler도 사람(?)이니까 실수할 때가 있죠. 필요하다고 판단해서 컴파일을 해놓았는데, 필요하지 않았던 경우나 오류가 있는 경우에는 재빠르게 decompile을 시도합니다.