Trình biên dịch không lớn lên nhờ những kịch bản tốt đẹp được soạn sẵn. Nó lớn lên khi ta dám ném nó vào vùng tối của những góc biên hỗn loạn và bắt nó tự đối mặt.
Sau khi đạt được fixed-point bootstrap cho subset compiler ở Chương 6 (Mốc M6), dự án DUY đứng trước một quyết định lớn. Chúng tôi có hai con đường: hoặc công bố tự trị và tiếp tục làm framework ở tầng ứng dụng, hoặc quay lại và port toàn bộ các tính năng phức tạp của full language vào native compiler và thực hiện quá trình tôi luyện (hardening).
Tôi chọn con đường thứ hai. Một trình biên dịch hệ thống chỉ an toàn khi nó tự mình thực thi các quy tắc an toàn của chính nó trên một quy mô lớn.
Chương này kể về chiến dịch port full language vào native compiler (Phase P, M7) và giai đoạn "chống ảo tưởng" (Phase Q và Phase R) trong các Sprint từ 99 đến 124. Đây là lúc DUY bước ra khỏi phòng lab yên bình để đối mặt với máy fuzzing, type differential checker, ceremony tái lập đa nền tảng, và xây dựng những viên gạch đầu tiên của hệ sinh thái (ecosystem) cho cộng đồng lập trình viên thực tế.
Biên dịch được fn, let, i32/bool và if/while (subset compiler) giống như việc anh xây được một cái chòi vững chãi để tránh mưa. Nhưng trình biên dịch thật cần một lâu đài. Nó cần struct để chứa dữ liệu, module để gom code, string thô, Result/Option/match để bắt lỗi, enum/? để rẽ nhánh, owned/move/view để kiểm soát memory, region để quản lý arena và effect/unsafe để vẽ ranh giới an toàn.
Sprint 99 đến 106 (Phase P) là một chuỗi các đợt tiến công dồn dập (waves) để port từng khối tính năng này sang native compiler viết bằng DUY.
Mỗi đợt port là một trận đánh thực sự. Khi đưa match và enum sang native, chúng tôi phải tự tay viết thuật toán exhaustiveness checking bằng chính subset ngữ pháp cực kỳ thô sơ của DUY Stage 1. Khi đưa region và view sang, chúng tôi phải tự tay thiết kế và biểu diễn cấu trúc đồ thị escape analysis mà không có sự trợ giúp của các thư viện collections động giàu tiện nghi của JavaScript. Code compiler phình lên gấp năm lần, các cấu trúc dữ liệu trở nên chằng chit, và áp lực rác trên heap tăng vọt.
Tôi nhớ thời điểm port xong module escape checker sang DUY. Khi biên dịch thử chính compiler, do hệ thống chưa có cơ chế tối ưu hóa bộ nhớ heap cho các mảng phẳng, compiler đã ngốn hết sạch RAM ảo của máy ảo Linux CI và bị hệ thống kill ngay lập tức (Out-Of-Memory). Tôi buộc phải dừng lại, refactor lại toàn bộ cấu trúc Node Allocation trong compiler để tái sử dụng các mảng phẳng cũ thay vì cấp phát mới vô tội vạ.
Cột mốc M7 exit (v1.0.0-preview) là một thành tựu lớn. Với 363 tests green hoàn toàn trên CI, native compiler mới đã chính thức gánh được toàn bộ ngôn ngữ. Nhưng đó cũng là lúc chúng tôi nhìn thấy những vết rạn đầu tiên xuất hiện dưới áp lực của quy mô thực tế.
Bình luận (0)
Đang tải bình luận...