본문 바로가기

C#/MSIL

CLR에서 돌아가는 언어를 뭔가를 만들어 보면서

https://github.com/pjc0247/ILIL

얼마 전에 ILIL이라는 이름으로, CLR환경에서 돌아가고 CIL로 컴파일되는 언어를 만들어보고자 하는 프로젝트를 진행했었다(개인적으로). 이번 프로젝트의 제작 의의는, 단순히 컴파일러 그 자체를 만들어보고, 결과물을 CIL로 출력해서, C# 또는 C++에서 콜해보는게 목적이었고, 어느 정도 작성한후에는 코드도 같이 Github에 공개할 예정이었다. (깃허브에 올려도 바다-나무님밖에 안보긴함)

그리고 최종적으로는 완성된 ILIL 컴파일러를 이용해 아래 코드와 같이 Reflection.Emit을 대체할 물건을 만드려고 했다.


대충 쉐이더 언어들처럼 돌아가는데, 런타임에 컴파일되고, 런타임에 바인딩된다. 기존 C#에서 런타임 메소드를 만드려면 Emit을 이용해서 바이트코드를 한땀한땀 작성하던것을 런타임 컴파일러가 돌아서 스크립트를 바이트코드로 대신 만들어주는것이다. 


어쨌든, 프로젝트는 하다가 접었는데, 요런 언어적인 물건은 처음 만들어보는거라 초창기부터 굉장히 이상한 구조로 작성하게 되었고, 언어 스펙을 구현하면서 굉장히 많은 예외케이스를 만났는데, 베이스 구조가 굉장히 이상하다보니 이러한 예외들을 깔끔하게 처리하지 못하고 코드가 완전히 엉켜버렸다. 
총체적 경험 부족이었고, 몇번 더 엎고, 처음부터 다시 하다보면 좀더 깔끔하게 만들 수 있을 것 같다는 생각이 든다. 
( 지금은 ILIL 프로젝트와는 별도로 Roslyn을 이용하여 Reflection.Emit을 대체하는 물건을 만드는데 성공했다. 사실 Roslyn이 워낙 사기라 내가 한건 없고, 그냥 사소한 코드만 몇줄 작성했다. )


이 프로젝트를 진행하면서 느낀 점은, CLR/CLI를 선택한것은 굉장히 멋진 선택이었다는 것인데, CLR/CLI 기반으로 언어를 작성하면 공짜로 얻을 수 있는것이 굉장히 많다. 요즘 어디선가 몇번씩 이름이 들려오는 scala, clojure등의 언어도 동일한 원리로 JVM에서 돌아가는 언어라고 한다.

아래는 이번 프로젝트를 진행해보면서 느낀, 중간 언어와/중간 언어로 컴파일되는 언어를 만들었을때의 장점이라고 생각되는 부분들이다. 


* VM

공짜로 VM이 제공된다, 이는 언어를 구현함에 있어서 VM 부분에는 신경쓰지 않고 순수하게 언어 그 자체 구현에 집중할 수 있음을 뜻한다. 

* 이미 설계된 instruction set

이런걸 만듬에 있어서 instruction set 설계부터 시작하는것이 또다른 재미요소일수도 있겠지만, 나같은경우는 그렇지 않다고 생각했고, 그냥 이미 다 만들어서 풀스펙 문서까지 작성되어 있는 CIL 명령어들을 가져다 썼다, 이는 엄청난 시간 절약이 되었다고 생각한다.

CIL Insruction set spec 문서

( 나는 위에 문서는 안보고 MSDN쪽에 C# API 문서를 보면서 만들었다. )

* 퍼포먼스

직접 만들어서 재보진 않았지만, MS의 절대고수님들이 만든 검증된 VM과 내가 조잡하게 만든 VM이 속도면에서 비교가 되지 않을 거라고 확신한다. 게다가 이렇게 만들면 CLR 버전이 올라감에 따라 공짜로 속도 업그레이드도 받을 수 있다.

* stdlib

새로 만드는 언어에서 stdlib로 .Net을 그대로 가져다 사용할 수 있다. 개인적으로는 C++, Ruby, Python의 stdlib가 아무리 날뛰어봤자 그 위에 군림하는게 .Net이라고 생각하는데, 과연 내가 아무리 언어를 만들고 나서 stdlib도 신경써서 만든다 해도 이거보다 잘 만들 수 있을까?

* 활용성 (호환성)

이렇게 빌드된 프로그램들은 곧바로 기존 C#, VB, Managed C++들과 호환된다.

기존에 진행중인 C# 프로젝트에 자신이 새로 만든 언어로 모듈을 만들어 붙이는것, 혹은 그 반대의 일이 가능하다는 것이다. 이건 좀 멋지다.

* 멀티 플랫폼

Mono!

사실 난 멀티 플랫폼에 별 관심이 없다. 이부분은 잘 모르겠다.

* 가비지 콜렉터

공짜로 가비지 컬렉터가 제공된다, 가비지 컬렉터를 직접 만들 필요도, 가비지 컬렉팅을 위한 내부적인 추가 코드를 생성할 일(ARC 처럼)도 없다. 

* 객체 지향

객체 지향 역시 공짜로 제공된다, CIL은 객체지향을 염두에 두고 만들어진 중간언어이다. 만약 x86 어셈블리등으로 출력되는 프로그램을 만든다고 하면, 객체지향 지원을 위해서 언어 레벨에서의 처리 이외에, 어셈블리를 빌드할때도 추가적인 처리가 필요할것이다. 

'C# > MSIL' 카테고리의 다른 글

[MSIL] 람다식의 캡쳐 구현하기  (0) 2016.09.01
[MSIL] 런타임 property 구현하기  (1) 2015.11.05
[MSIL] beforefieldinit  (1) 2015.11.02
[MSIL] for loop  (1) 2015.11.02