
C++로 구현한 register VM과 자체 네이티브 JIT를 가진 프로그래밍 언어
.sura 소스를 register bytecode로 컴파일해 실행합니다. 타입 검사는 기본이 strict이고,--jit를 켜면 함수가 x86-64·ARM64 네이티브 코드로 내려갑니다.
Windows x64는 전체 컴파일러가, Linux x86-64와 ARM64는 배열 인덱싱과 가드된 산술은 인라인으로, 문자열·딕셔너리는 VM helper로 처리하는 baseline이 담당합니다. x86-64 두 tier는 루프 안의 숫자를 레지스터에 두는 루프 레지스터 캐시와, 루프 불변 배열의 검사를 루프 진입 때 한 번만 하는 컨테이너 끌어올리기를 공유합니다. 가드에 실패한 코드는 같은 명령에서 VM이 이어 받으므로 결과는 VM만으로 실행했을 때와 같습니다.
Overview
같은 소스, 플랫폼마다 다른 네이티브 계층
fib(30)을 다섯 번 실행한 최속값입니다. Windows x64 전체 JIT와 Linux x86-64 baseline이 같은 시간에 도달하고, 두 경로 모두 안정 테스트 158개를 VM과 같은 출력으로 통과합니다.
func fib(n) do
if n <= 1 then
return n
end
return fib(n - 1) + fib(n - 2)
end
print(fib(30))832040Quick start
시작하기
일반적인 Sura 프로그램의 생성, 실행, 테스트에는 Python, Node.js, CMake, FFmpeg가 필요하지 않습니다.
- Microsoft Store에서 설치
SuraTeam이 게시한 무료 Windows 앱입니다. Store 페이지 열기
- 새 PowerShell에서 확인
sura --versionsura --repl - Starter 프로젝트 만들기
surapkg new my_appcd my_app - 실행하고 테스트하기
surapkg runsurapkg test
| 01 | Hello | 출력과 문자열 보간 | 01_hello.sura |
| 02 | 값과 변수 | 기본 값과 타입 힌트 | 02_values.sura |
| 03 | 제어 흐름 | 조건문과 반복문 | 03_control_flow.sura |
| 04 | 함수 | 매개변수와 반환값 | 04_functions.sura |
| 05 | 컬렉션 | 배열과 딕셔너리 | 05_collections.sura |
| 06 | 클래스 | 생성자와 메서드 | 06_classes.sura |
| 07 | 파일 | 쓰기, 읽기, 삭제 | 07_files.sura |
| 08 | JSON | 직렬화와 파싱 | 08_json.sura |
| 09 | HTTP 도구 | URL과 상태 코드 | 09_http_helpers.sura |
| 10 | 비동기 | 작업 생성과 대기 | 10_async.sura |
| 11 | 오류 처리 | try, catch, finally | 11_errors.sura |
| 12 | 테스트 | 내장 assertion | 12_testing.sura |
기능별 선택 의존성. 영상 처리는 FFmpeg, Python 연동은 Python, JavaScript 타깃과 VS Code 도구 검증은 Node.js가 필요합니다.
Examples
예제
모두 현재 엔진으로 실행해 출력을 확인한 것입니다. 배열·딕셔너리 예제는 Linux와 ARM64에서도 helper를 통해 네이티브 코드로 컴파일됩니다.
surapkg new hello_sura
cd hello_sura
surapkg run -- Sura
surapkg testNative tiers · main 2026-09-02
플랫폼별 네이티브 계층
같은 --jit 플래그가 플랫폼마다 어디까지 네이티브 코드를 내보내는지 그대로 적었습니다. 어느 계층이든 결과는 register VM과 같아야 하고, 그 사실을 differential 검사가 확인합니다.
| OS | 아키텍처 | backend | 범위 |
|---|---|---|---|
| Windows | x86-64 | Win64 전체 컴파일러 | 순수 숫자 함수는 baseline으로 먼저 보내고, 나머지는 인라인 캐시를 가진 전체 컴파일러가 맡는다. 두 tier 모두 루프 안의 숫자 레지스터를 XMM6–XMM15에 상주시키는 루프 레지스터 캐시를 쓴다(메모리 슬롯도 항상 갱신). 루프가 쓰지 않는 배열 컨테이너의 객체 검사는 루프 진입 때 한 번만 하고 GCArray*를 R14·R15·RSI·RDI에 둔다(7차 개정). warm-up 뒤 부분 컴파일, UNWIND_INFO 등록(XMM 저장·GPR push 포함). |
| Linux | x86-64 | System V baseline (7차 개정) | 숫자 연산·비교·나눗셈·전역 읽기·순수 숫자 함수 간 직접 호출에 더해 배열 인덱싱·push·len·dict has를 인라인으로 내보내고, 타입이 증명되지 않은 산술·비교·분기는 태그 검사 뒤 인라인으로 계산한다. 루프 안에서 산술이 읽고 쓰는 레지스터는 XMM 레지스터에 상주하고(호출 뒤 재적재), 메모리 슬롯은 항상 최신이다. 루프가 쓰지 않는 배열 컨테이너의 검사는 루프 진입 때 한 번만 하고 GCArray*를 R14·R15에 둔다. 문자열·딕셔너리 읽기와 쓰기·필드·in·for…in·일반 호출·그 밖의 메서드 호출은 VM helper 17개를 호출한다. |
| Windows · Linux · macOS | ARM64 | AAPCS64 baseline | Linux x86-64 baseline과 같은 범위. ARM64 CI 러너의 단위 테스트와 unicorn 명령 단위 에뮬레이션(46/46)으로 검증. 벤치마크 표는 재측정 예정. |
| macOS | x86-64 | 없음 | 네이티브 emitter가 없고 register VM이 전체를 실행한다. macos-15-intel 러너에서 같은 테스트를 통과한다. |
가드와 deopt
네이티브 코드는 값이 숫자인지 같은 가드를 통과할 때만 계속 실행하고, 실패하면 그 명령의 위치를 기록한 뒤 register VM이 이어 받습니다. helper가 예외를 내는 경우도 같은 경로로 VM과 같은 오류를 냅니다.
하이브리드 프레임
네이티브 직접 호출은 callee가 helper에 닿을 수 있을 때만 프레임을 VM 값 스택에 올려 GC가 볼 수 있게 하고, fib처럼 helper에 닿지 않는 callee는 기계 스택을 씁니다. helper를 더한 뒤에도 fib 비용이 그대로인 이유입니다.
검증 방법
같은 프로그램을 VM과 JIT로 실행해 출력을 비교하는 differential 스크립트, 이식형 baseline smoke, 안정 테스트 158개를 매 변경마다 돌립니다. ARM64는 ubuntu-24.04-arm·macos-15 러너의 단위 테스트에 더해 unicorn 명령 단위 에뮬레이션으로 프레임·deopt 경로를 확인합니다.
아직 남은 것
Linux baseline에서는 딕셔너리 읽기·쓰기와 필드 접근을 아직 helper가 맡습니다. 루프 불변 피연산자의 태그 검사를 루프 밖으로 끌어올리는 것, 숫자 호출 규약, 필드 인라인 캐시, ARM64 루프 레지스터 캐시와 벤치마크 재측정, macOS x86-64 backend가 다음 과제입니다.
Implementation
구현 범위
실행기, JIT, 타입 검사, 메모리 관리, 도구, 외부 연동, 실험 타깃까지 현재 구현된 범위입니다.
| 영역 | 구현 | 비고 |
|---|---|---|
| 실행 | register bytecode + register VM | 기본 실행 경로. lexer → parser → strict typecheck → bytecode |
| JIT | 자체 x86-64·ARM64 emitter | --jit 선택형. Win64 전체 컴파일러, SysV·AAPCS64 baseline |
| 타입 | strict-by-default 점진적 타입 검사 | --legacy-types는 소스 실행에서만 선택 가능 |
| 메모리 | NaN-boxed Value, mark-sweep GC, 문자열·배열·딕셔너리·인스턴스는 타입별 free list 풀에서 할당, 딕셔너리는 삽입 순서를 지키는 compact open-addressing 표, 문자열 키의 해시는 문자열 객체에 캐시, 할당 경로는 임베딩 컨텍스트가 생기기 전까지 잠금 없음 | 네이티브 코드는 helper 안에서만 수집기를 만난다 |
| 도구 | formatter, lint, test, profile, LSP, DAP | starter 프로젝트 생성, VS Code 확장 |
| 연동 | FFI 1.2, plugin ABI 1.1, Python bridge | 기능별로 외부 도구가 필요할 수 있음 |
| 타깃 | JavaScript, WebAssembly (실험) | JS 41 full · 0 partial, Wasm 28 full · 13 partial |
Verification
검증 기록과 성능
릴리스 기록과 main 브랜치 기록을 구분해 적었습니다. 뒤처진 항목도 같이 둡니다.
Release 1.11.1
| Stable runtime suite | VM 107/107 · JIT 107/107 |
| Starter examples | 외부 의존성 없이 12/12 실행 |
| Release evidence | 157/157 · 2026-07-17 |
main · 2026-09-02
| Stable suite | 158/158 · VM과 JIT |
| Differential | VM ↔ JIT 출력 비교 |
| Cross Platform Smoke | Ubuntu · Ubuntu ARM64 · macOS ARM64 · macOS Intel · ASan+UBSan · TSan |
| Benchmark gate | fib jit_ms 회귀 35% 이내 · Windows 러너 |
Benchmarks
언어 간 벤치마크
i5-12400F. 같은 8개 작업을 각 언어로 작성해 5회 중 최속을 ms로 적었습니다. 낮을수록 빠릅니다. 모든 구현은 같은 체크섬을 출력합니다.
Windows x64 · 전체 JIT
| 언어 | fib | numeric | array | string | dict | sort | object | matmul |
|---|---|---|---|---|---|---|---|---|
| C++ -O2 | 0.9 | 1.4 | 2.1 | 2.9 | 16.0 | 16.5 | 0.3 | 5.7 |
| Node 24 | 7.6 | 1.7 | 8.4 | 2.6 | 17.0 | 73.2 | 0.4 | 10.8 |
| Sura JIT | 7.0 | 3.1 | 4.9 | 2.1 | 17.0 | 8.7 | 0.8 | 27.7 |
| Sura VM | 73.8 | 67.5 | 62.6 | 12.5 | 91.4 | 33.8 | 79.5 | 575.5 |
| Python 3.12 | 77.8 | 167.9 | 90.3 | 7.3 | 33.5 | 86.1 | 75.1 | 637.5 |
Linux x86-64 · helper 포함 baseline (WSL2, 같은 기계)
| 언어 | fib | numeric | array | string | dict | sort | object | matmul |
|---|---|---|---|---|---|---|---|---|
| C++ -O2 | 0.8 | 1.4 | 0.8 | 1.4 | 13.4 | 15.7 | 0.3 | 4.8 |
| Sura JIT | 7.2 | 4.3 | 7.8 | 2.4 | 18.3 | 12.1 | 11.0 | 54.0 |
| Sura VM | 86.9 | 87.9 | 69.3 | 10.5 | 76.2 | 33.4 | 76.5 | 790.7 |
| Python 3.14 | 59.8 | 109.3 | 56.7 | 3.9 | 22.6 | 73.6 | 45.1 | 467.2 |
Windows x64에서는 이 묶음의 모든 함수가 JIT로 컴파일되어 기하평균으로 CPython보다 약 14.2배 빠릅니다. 배열 인덱싱·push·len과 딕셔너리 has는 인라인이고, 단순 생성자는 할당 한 번, 루프 밖으로 나가지 않는 레코드는 할당 없이 프레임 슬롯에 필드를 둡니다. 캐시가 직접 내보내는 연산만으로 된 루프는 레지스터를 XMM에만 두고(write-back) helper 호출 앞과 루프를 나갈 때만 프레임에 되쓰며, 비교는 바로 뒤 분기와 융합되고, 나눗셈·나머지는 인라인이며, 숫자 매개변수는 진입 시 한 번만 검사합니다. 인덱스 명령으로 넘어가는 임시 복사는 접히고, 딕셔너리는 마지막으로 조회한 키의 슬롯을 기억해 같은 키의 has·읽기·쓰기가 한 번만 탐사합니다. 크기가 변할 수 없는 루프에서는 배열의 data·끝 포인터를 미리 꺼내 두어 원소 접근이 두 명령입니다. 산술은 먼저 계산하고 결과가 NaN인지 한 번만 봅니다: 숫자가 아닌 값은 모두 NaN 패턴이라 연산을 통과하면 결과도 NaN이 되므로, 피연산자마다 하던 태그 검사가 결과 검사 하나로 줄고 비교는 검사가 아예 없습니다. 끌어올린 배열은 접근마다 널 검사를 하지 않고(범위 비교가 이미 걸러냅니다), 바로 뒤 명령만 읽는 숫자 상수는 프레임에 쓰지 않고 상수 배열에서 바로 읽습니다. 인덱스가 정수 step으로만 늘어나는 루프에서는 레지스터가 배열 시작이 아니라 원소 포인터를 들고 반복마다 step만큼 나아가므로, 접근이 경계 비교와 이동 두 명령입니다. 치환된 생성자가 읽지 않는 클래스 로드와 레코드 별칭 복사는 내보내지 않고, 2의 거듭제곱 상수로 나누기는 역수 곱하기로, 나머지는 하위 비트로 계산합니다. Linux x86-64 baseline도 같은 인라인 경로(배열 인덱싱·push·len·dict has, 태그 검사 후 산술·비교)와 루프 레지스터 캐시·컨테이너 끌어올리기·인스턴스 필드 인라인 캐시(사이트의 IC를 실행 시점에 읽어 재컴파일 없이 데워짐)를 갖게 되어 전체로는 약 5.3배 빠릅니다. 딕셔너리 읽기·쓰기만 아직 helper를 부르지만, compact 표와 키 해시 캐시 덕에 dict 열도 CPython을 앞섭니다. C++·Rust·Go·C#·Java 전체 표와 재현 방법은 저장소의 benchmarks/cross_language에 있습니다.
Downloads · Windows x64 · 1.11.1
다운로드
기본 설치는 Microsoft Store입니다. 게시자 SuraTeam, 제품 ID 9P5JFKSWTP0P, 무료. Linux·ARM64 네이티브 계층은 소스 빌드로 사용할 수 있으며 다음 릴리스에 포함됩니다.
직접 다운로드 · Authenticode 서명 없음
아래 파일은 Store 패키지와 별개인 보조 경로입니다. Chrome이나 Windows가 경고할 수 있으므로 일반 사용자는 Store 설치를 권장합니다.
| 파일 | 크기 | SHA-256 |
|---|---|---|
| SuraLanguageSetup-1.11.1.exe Windows 설치기 | 14.3 MB | b88bdb651e4d443064418a88abc6482f305b65339be614d80c4998f8add9c38a |
| SuraLanguage-1.11.1-windows-x64.zip Windows 압축 파일 | 5.1 MB | fed5291869e66a1a0da49d59b31482ef6c2843d32a4f1bb4c0c07ae12c2a3277 |
| SuraLanguage-VSCode-1.11.1.vsix VS Code 확장 | 0.2 MB | 86d1dbb4a8efc7459da1a6b8f02af4fed958ffe92433060ccf8bace3a00dae6a |
Reference
언어 레퍼런스
문법, 실행 모델, CLI, 표준 라이브러리 API 528개 서명, 플랫폼별 제한, 검증 기록을 한 HTML 문서와 구조화 JSON으로 제공합니다.