웹어셈블리가 등장한 이후 오랫동안 개발자들은 이를 스택 기반의 가상 머신으로 인식해 왔습니다. 공식 명세서와 위키백과 같은 주요 자료들도 이를 명확히 정의하며, 웹 환경에서 실행되는 바이트코드라는 맥락에서 스택 머신이라는 분류는 자연스러운 통념으로 자리 잡았습니다. 하지만 최근 기술 커뮤니티를 중심으로 이 정의가 실제 구현의 본질을 제대로 반영하지 못한다는 지적이 힘을 얻고 있습니다. 단순히 이름이나 문서상의 분류를 넘어, 실제 명령어 집합을 손으로 작성하거나 컴파일러를 구현해 보는 과정에서 기존 스택 머신과의 결정적인 차이가 드러나기 시작한 것입니다.
가장 핵심적인 논쟁점은 스택 조작 명령어의 부재입니다. 전통적인 스택 머신인 자바 가상 머신이나 포스트스크립트 같은 언어들은 dup, swap, rot 과 같은 명령어를 통해 스택 내부의 값을 자유롭게 재배치하고 재사용합니다. 반면 웹어셈블리는 이러한 연산자가 거의 존재하지 않습니다. 값의 재사용이나 공통 부분 식 제거를 위해서는 스택을 직접 조작하는 대신 지역 변수를 명시적으로 할당해야 합니다. 이는 스택이 데이터 흐름을 위한 물리적인 저장소라기보다는, 레지스터 머신에서 연산 결과를 임시로 보관하는 레지스터 역할을 수행하는 것과 유사한 구조임을 시사합니다.
이러한 구조적 특징은 웹어셈블리가 레지스터 머신의 명령어 인코딩 방식을 차용했음을 보여줍니다. 레지스터 머신은 명령어가 상대적으로 길어지지만, LOAD 나 STORE 같은 연산 횟수를 줄일 수 있는 장점이 있습니다. 웹어셈블리 역시 스택을 연산의 매개체로 사용하지만, 그 본질은 레지스터 기반의 연산 로직을 역폴란드 표기법으로 인코딩한 것에 가깝습니다. 특히 멀티값 확장 기능이 도입되기 전의 제어 흐름 블록들이 스택과 완전히 단절되어 있었다는 사실은, 스택이 웹어셈블리의 근본적인 설계 철학이라기보다는 특정 시기의 인코딩 기술적 선택에 불과했을 가능성을 높여줍니다.
이러한 재해석은 실제 개발 현장에 즉각적인 영향을 미칩니다. 웹어셈블리에 C 나 다른 언어를 컴파일하는 작업을 수행할 때, 전통적인 스택 머신 최적화 기법을 그대로 적용하면 예상치 못한 동작을 보일 수 있습니다. 예를 들어, 스택 값을 재사용하기 위해 dup 명령어를 기대했다가 지역 변수 할당 코드가 삽입되는 것을 발견하는 경우가 많습니다. 또한 텍스트 형식인 WAT 이 Lisp 같은 S-식 형태로 표현되는 것도 단순한 문법적 설탕이 아니라, 계층적인 블록 구조와 지역 변수 스코프를 명확히 하기 위한 설계 의도의 결과로 해석될 수 있습니다.
기술계의 이 같은 논의는 웹어셈블리가 단순한 웹용 바이트코드를 넘어, 독립적인 실행 환경으로서의 정체성을 확립해 가는 과정임을 보여줍니다. 스택 머신이라는 레이블이 붙어 있었지만, 실제로는 레지스터 머신의 효율성과 스택의 간결함을 절충한 하이브리드 형태에 가깝다는 사실이 밝혀지면서, 향후 컴파일러 최적화 전략이나 가상 머신 설계에 대한 새로운 기준이 마련될 것으로 보입니다. 개발자들은 이제 웹어셈블리를 다룰 때 스택의 깊이보다는 레지스터 매핑과 지역 변수의 생명주기에 더 집중해야 하며, 이는 웹어셈블리 생태계가 성숙해가는 중요한 지표가 될 것입니다.