
जीवनकाल और अन्य शोधन प्रकारों के लिए जांचकर्ता
Checkers of
Lifetimes and other
Refinement types
Zig के लिए
वीडियो: https://www.youtube.com/watch?v=mf0WzTOe-40 प्रायोजन: https://buymeacoffee.com/dnautics
hn पर चर्चा करें: https://news.ycombinator.com/item?id=42923829
lobste.rs पर चर्चा करें: https://lobste.rs/s/9sitsj/clr_checker_for_lifetimes_other
लाइव डेमो वीडियो: https://www.youtube.com/watch?v=ZY_Z-aGbYm8
यह प्रोजेक्ट Zig कम्पाइलर के लिए एक Zig ट्रांसपाइलर बनाता है, जो AIR (एब्स्ट्रैक्ट इंटरमीडिएट रिप्रेज़ेंटेशन) को Zig सोर्स कोड में रूपांतरित करता है जो कम्पाइल टाइम पर स्थैतिक विश्लेषण करता है। जनरेटेड विश्लेषक मेमोरी सुरक्षा समस्याओं जैसे कि उपयोग-से-पहले असाइनमेंट, उपयोग-के-बाद-मुक्त, स्टैक पॉइंटर एस्केप, साथ ही Zig-विशिष्ट UB जैसे गैर-शून्यता अभिकथन, टैग किए गए यूनियन उल्लंघन, या fieldParentPtr दुरुपयोग को पकड़ता है।
लक्ष्य Zig में Rust-स्तरीय मेमोरी सुरक्षा गारंटी को AIR के स्थैतिक विश्लेषण के माध्यम से लाना है, बिना भाषा में ही बदलाव किए।
CLR Zig कम्पाइलर के एक फोर्क किए गए संस्करण पर निर्भर करता है (जो zig/ में एक सबमॉड्यूल के रूप में शामिल है) जो AIR को बाहरी प्लगइन्स पर रूट करने का समर्थन जोड़ता है। जब -ofmt=air -fair-out=<plugin.so> के साथ आमंत्रित किया जाता है, तो कम्पाइलर निर्दिष्ट शेयर्ड लाइब्रेरी को लोड करता है और उत्पन्न AIR को प्रसंस्करण के लिए उस पर भेजता है।
CLR का उद्देश्य प्रोग्राम को ऐसे जीवनचक्र पैटर्न की ओर धकेलना है जो स्पष्ट और स्थानीय रूप से सत्यापनीय हों, न कि केवल हर तकनीकी रूप से मान्य Zig प्रोग्राम को पहचानना। जब दो निरूपण संभव हों, तो CLR उसे प्राथमिकता देता है जो संसाधन की स्थिति को प्रकार और नियंत्रण-प्रवाह संरचना में दृश्यमान बनाता है।
उदाहरण के लिए, किसी गैर-वैकल्पिक फ़ाइल डिस्क्रिप्टर को सशर्त रूप से बंद करने से बचें:
const file = try std.fs.cwd().openFile(path, .{});
if (should_close) {
file.close(); // Bad: file is ambiguously open after this branch.
}
सशर्त स्वामित्व को एक वैकल्पिक के साथ प्रस्तुत करना पसंद करें:
var file: ?std.fs.File = null;
if (should_open) {
file = try std.fs.cwd().openFile(path, .{});
}
if (file) |open_file| {
open_file.close();
}
एक गैर-वैकल्पिक डिस्क्रिप्टर को सशर्त रूप से बंद करना शाखा के बाद उसके जीवनचक्र को अस्पष्ट छोड़ देता है। CLR की अभिप्रेत नीति इस पैटर्न को अस्वीकार करना है, बजाय एक स्थायी "शायद बंद" स्थिति ले जाने के।
यही सिद्धांत आवंटित पॉइंटर्स पर भी लागू होता है। व्युत्पन्न पॉइंटर से मुक्त न करें:
const allocation = try allocator.alloc(u8, size);
const payload = allocation[header_size..];
allocator.free(payload); // Bad: payload is not the allocation base.
आवंटन-आधार पॉइंटर को डीलोकेशन के लिए उपलब्ध रखें, और व्युत्पन्न पॉइंटर का उपयोग केवल एक्सेस के लिए करें:
const allocation = try allocator.alloc(u8, size);
defer allocator.free(allocation);
const payload = allocation[header_size..];
use(payload);
एक फ़ील्ड पॉइंटर, सबस्लाइस, या अंकगणित द्वारा उत्पादित पॉइंटर को मुक्त करना अस्वीकार कर दिया जाता है जब तक कि एक दस्तावेजित आंतरिक नियम आवंटन-आधार प्रोवेनेंस को पुनर्स्थापित न करे।
ये नीतियाँ डिफ़ॉल्ट रूप से सख्त हैं क्योंकि वे सरल, अधिक समीक्षा योग्य संसाधन जीवनचक्र वाला कोड उत्पन्न करती हैं। भविष्य में एक असुरक्षित एनोटेशन तंत्र चयनित GIDs या संचालन को व्यक्तिगत विश्लेषणों से बाहर निकलने की अनुमति देगा। यह ऐसे कोड का समर्थन करेगा जो प्रदर्शन के लिए जानबूझकर कमजोर जाँच स्वीकार करता है, बिना शेष प्रोग्राम के लिए डिफ़ॉल्ट मॉडल को कमजोर किए।
यह Zig में मूल Elixir-आधारित प्रूफ-ऑफ-कॉन्सेप्ट का एक सक्रिय पुनर्लेखन है। Zig कार्यान्वयन एक कम्पाइलर प्लगइन के रूप में लोड होता है और सीधे AIR का विश्लेषण करता है।
वर्तमान में कार्यान्वित:
std.mem.Allocator इंटरफ़ेस कवरेज:
create/destroy - एकल आइटम आवंटनalloc/free - स्लाइस आवंटन (alignedAlloc, allocSentinel आदि सहित)realloc/remap - पुरानी-स्लाइस-मुक्त ट्रैकिंग के साथ स्लाइस पुनःआवंटनdupe/dupeZ - स्लाइस डुप्लिकेशनinit/deinit/allocator - पूर्ण एरीना जीवनचक्रstd.process.args, std.mem.asBytes, std.HashMap, और आवंटनकर्ता/फ़ाइल API के लिए स्टैण्डर्ड लाइब्रेरी बाउंड्री कमीstd.HashMap परिशोधन कैनोनिकल मेटाडेटा/कुंजी/मान भंडारण पहचान के साथ put, get, getPtr, और मान पुनरावृत्ति मेंposix.open/close/dup/dup2/socket/accept/epoll_create/pipe ट्रैकिंगयोजनाबद्ध (विवरण के लिए LIMITATIONS.md देखें):
sudo apt install batsवेंडर्ड Zig कम्पाइलर और libclr प्लगइन को समान ऑप्टिमाइज़ेशन स्तरों के साथ बनाया जाना चाहिए। बेमेल ऑप्टिमाइज़ेशन स्तर segfaults का कारण बनेंगे।
# कस्टम Zig कम्पाइलर को ReleaseFast के साथ बनाएं (पहली बार, या सबमॉड्यूल बदलने के बाद)
cd zig && zig build --zig-lib-dir lib -Doptimize=ReleaseFast && cd ..
# CLR प्लगइन को मैचिंग ऑप्टिमाइज़ेशन के साथ बनाएं
zig build -Doptimize=ReleaseFast
डेवलपमेंट/डीबगिंग के लिए, दोनों के लिए ReleaseSafe या Debug का उपयोग करें:
# ReleaseSafe (सुरक्षा जाँच के साथ, थोड़ा धीमा)
cd zig && zig build --zig-lib-dir lib -Doptimize=ReleaseSafe && cd ..
zig build -Doptimize=ReleaseSafe
# Debug (पूर्ण डीबग जानकारी, सबसे धीमा)
cd zig && zig build --zig-lib-dir lib && cd ..
zig build