Chuyển Đổi Từ Lua 5.2 Sang 5.3
Vào đầu năm 2015, phiên bản Lua 5.3 rc3 đã chính thức ra mắt. Nếu nhìn lại lịch sử phát hành của Lua 5.2, phiên bản final của nó được công bố vào ngày 17 tháng 12 năm 2011, tức là chỉ sau chưa đầy một tháng kể từ phiên bản rc1 (24/11/2011) và sau rc8. Điều này cho thấy khả năng cao phiên bản chính của 5.3 sẽ sớm hoàn thiện. (Phiên bản rc1 của 5.3 được phát hành vào ngày 17/12/2014).
Lần nâng cấp này gần như không thay đổi về mặt cú pháp ngôn ngữ, nhưng các tính năng mới như hỗ trợ kiểu int64, thư viện string.pack và utf8 thực sự mang lại nhiều lợi ích thiết thực cho lập trình viên. Do đó, tôi khuyến khích mạnh mẽ các dự án đang sử dụng Lua 5.2 nên chuyển đổi sang 5.3 càng sớm càng tốt. So với lần nâng cấp từ 5.1 lên 5.2 (với sự biến mất của hàm setfenv
và sự xuất hiện của _ENV
), quá trình này có phần nhẹ nhàng hơn nhiều.
Kế hoạch nâng cấp cho Skynet
Khi Lua 5.3 chính thức được phát hành, tôi dự định sẽ cập nhật phiên bản Lua được tích hợp sẵn trong Skynet lên 5.3, đồng thời tiến hành chuẩn bị cho việc phát hành Skynet 1.0. Trong môi trường ứng dụng Skynet, tôi vẫn cần chỉnh sửa một số phần của máy ảo Lua để cho phép các máy ảo khác nhau có thể chia sẻ đối tượng Proto. Tuy nhiên, công việc này có thể tạm hoãn lại cho đến khi phiên bản chính thức được công bố.
Hiện tại, chúng ta đã có thể bắt đầu nâng cấp từng thư viện Lua trong hệ thống Skynet. Trên trang GitHub của dự án, tôi đã tạo nhánh lua53 và thực hiện một số thay đổi ban đầu. Mong muốn có sự tham gia của các bạn để cùng kiểm tra (review) đoạn mã nguồn này. Các bạn quan tâm có thể đối chiếu với các commit mới nhất để nắm rõ các thay đổi đã thực hiện.
Những thay đổi bắt buộc
Một trong những điều cần làm là loại bỏ toàn bộ các hàm liên quan đến kiểu unsigned. Lua 5.3 đã loại bỏ các API như lua_pushunsigned
hay lua_tounsigned
, thay thế chúng bằng lua_pushinteger
và các hàm tương tự. Các hàm này mặc định thao tác với kiểu dữ liệu lua_Integer
, vốn được định nghĩa là kiểu long long (đảm bảo 64 bit). Theo tài liệu hướng dẫn, bạn nên ưu tiên sử dụng lua_Integer
trong mã nguồn. Nếu thực sự cần kiểu số nguyên không dấu, bạn có thể ép kiểu trong mã C.
Sau khi hoàn tất các thay đổi này, toàn bộ mã nguồn sẽ có thể biên dịch thành công.
Tối ưu hóa thư viện liên quan đến tuần tự hóa (serialization)
Phiên bản Lua 5.3 hỗ trợ kiểu số nguyên bản địa (native integer), loại bỏ việc lưu trữ số dưới dạng double như trước đây. Điều này đòi hỏi các thư viện liên quan đến tuần tự hóa (như seri, bson,…) phải được điều chỉnh để tận dụng lợi thế này.
Trong các phiên bản cũ, để phân biệt giữa số thực và số nguyên trong Lua, tôi từng sử dụng cách gọi lua_tonumber
và lua_tointeger
rồi so sánh giá trị. Tuy nhiên, Lua 5.3 cung cấp hàm lua_isinteger
hiệu quả hơn nhiều để kiểm tra trực tiếp.
Với khả năng xử lý số nguyên 64 bit, việc dùng lightuserdata
để lưu trữ số dài đã trở nên thừa thãi. Tôi đã loại bỏ thư viện int64
và điều chỉnh các thư viện liên quan như pbc (đã hoàn tất, sẽ công bố sau), seri, bson, redis,…
Chú ý: Trong quá trình điều chỉnh, tôi phát hiện một lỗi liên quan đến kiến trúc không cho phép truy cập địa chỉ không căn chỉnh (unaligned access). Vấn đề này đã được khắc phục cùng lúc.
Những thay đổi quan trọng khác
Lua 5.3 đã loại bỏ hàm __ipairs
và viết lại hoàn toàn thư viện table. Đây là minh chứng cho triết lý “liều lĩnh” của đội ngũ phát triển Lua khi sẵn sàng dẹp bỏ những thứ cũ để giữ tính nhất quán (Conceptual Integrity) – điều mà tôi luôn ngưỡng mộ.
Thư viện bit32
cũng đã được xóa bỏ (trừ khi bật chế độ tương thích 5.2). Thay vào đó, Lua 5.3 hỗ trợ các toán tử thao tác bit bản địa. Ví dụ:
~
thay choxor
(vì^
đã được dùng cho phép mũ).
Trong mã nguồn, tôi phát hiện thư viện bit32
được sử dụng chủ yếu trong driver MySQL được chuyển từ OpenResty. Tuy nhiên, với hàm string.pack mới, việc dùng toán tử bit trở nên không cần thiết. Ví dụ:
|
|
có thể được thay thế bằng:
|
|
Cải tiến phong cách lập trình Lua
Trong quá trình chuyển đổi, tôi nhận thấy một số đoạn mã trong OpenResty chưa thực sự “Lua-style”. Ví dụ hàm _dump
sau:
|
|
có thể viết lại theo phong cách Lua chuẩn như sau:
|
|
Cách viết mới không chỉ ngắn gọn hơn mà