<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rezo</title>
    <description>The latest articles on DEV Community by Rezo (@gervantofryvia).</description>
    <link>https://dev.to/gervantofryvia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2613363%2Feef0705d-7486-4a87-95a3-894950f4d45d.jpg</url>
      <title>DEV Community: Rezo</title>
      <link>https://dev.to/gervantofryvia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gervantofryvia"/>
    <language>en</language>
    <item>
      <title>პროგრამირების ენა Buk.</title>
      <dc:creator>Rezo</dc:creator>
      <pubDate>Wed, 16 Sep 2026 08:00:30 +0000</pubDate>
      <link>https://dev.to/gervantofryvia/programirebis-ena-buk-35ji</link>
      <guid>https://dev.to/gervantofryvia/programirebis-ena-buk-35ji</guid>
      <description>&lt;h2&gt;
  
  
  რატომ კიდევ ერთი სისტემური პროგრამირების ენა?
&lt;/h2&gt;

&lt;p&gt;Rust-მა პრაქტიკაზე დაამტკიცა, რომ უსაფრთხო სისტემური პროგრამირების ენების შექმნა garbage collector-ის გარეშე შესაძლებელია და ეს ნიშა ძალიან მოთხოვნადია. &lt;/p&gt;

&lt;p&gt;C/C++-ზე დაწერილმა პროგრამებმა ათწლეულების განმავლობაში ათასობით კრიტიკული შეცდომა დააგროვეს, რის გამოც ხდებოდა უამრავი exploit-ის შექმნა, სისტემების გატეხვა და ასე შემდეგ. მეხსიერების ბაგები არის ექსპლოიტების ერთ ერთი ყველაზე მთავარი წყარო. გარდა ამისა მეხსიერების ბაგების გამო პროგრამები შეიძლება არასტაბილური იყოს, იქრაშებოდეს და ასე შემდეგ.&lt;/p&gt;

&lt;p&gt;მაგრამ Rust-ს თავისი ფასი აქვს. ის ძალიან რთულია და მისი იმპლემენტაციის სპეციფიკიდან გამომდინარე უსაფრთხო მეხსიერების რეალიზაცია მხოლოდ კომპილატორის დონეზე არ ხდება, არამედ გადადის თვითონ ენაში და ტიპების სისტემაშიც, რის გამოც ის არ არის კითხვადი და ძალიან რთული ასათვისებელია სემანტიკურად. &lt;/p&gt;

&lt;p&gt;Buk-ის შექმნის დროს ჩემს თავს დავუსვი ასეთი კითხვა: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;შეიძლება თუ არა Rust-ის მსგავსი compile-time memory safety მივიღოთ უფრო პატარა source-level მოდელით?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ანუ სირთულე კი არ გავაქროთ, რაც შეუძლებელია, არამედ მისი დიდი ნაწილი კომპილატორში გადავიტანოთ. ამასთან ერთად გავასწოროთ Rust-ის მიერ დაგროვებული tech debt-ი. &lt;/p&gt;




&lt;h1&gt;
  
  
  Ownership და Borrow Checker
&lt;/h1&gt;

&lt;p&gt;სანამ დეტალებზე გადავიდოდეთ, ორი ძირითადი ტერმინი განვმარტოთ.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ownership&lt;/strong&gt; ნიშნავს, რომ კონკრეტულ value-ს ჰყავს owner ("მფლობელი"), ანუ პროგრამის ის ნაწილი, რომელიც მასზე და მის რესურსებზეა პასუხისმგებელი.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;LoadDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;აქ ცვლადი &lt;code&gt;document&lt;/code&gt; არის owner (LoadDocument-ის მიერ დაბრუნებული მნიშვნელობის ექსკლუზიური "მფლობელი").&lt;/p&gt;

&lt;p&gt;თუ document ცვლადში არსებული მნიშვნელობა სხვა ფუნქციას მთლიანად გადავეცით, ownership-იც მასზე გადადის და ის ხდება ექსკლუზიური მფლობელი.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ამის შემდეგ ძველი მფლობელი ამ მნიშვნელობას ვეღარ გამოიყენებს.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Borrowing&lt;/strong&gt; ნიშნავს მნიშვნელობის დროებით გამოყენებას ownership-ის გადაცემის გარეშე, ანუ "თხოვებას".&lt;/p&gt;

&lt;p&gt;მაგალითად:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;აქ ფუნქციას-ს მხოლოდ დროებითი წვდომა აქვს, ხოლო ექსკლუზიური მფლობელი ისევ &lt;code&gt;document&lt;/code&gt; ცვლადი რჩება.&lt;/p&gt;

&lt;p&gt;Borrow შეიძლება იყოს მხოლოდ წასაკითხად, ან exclusive mutation-ისთვის.&lt;/p&gt;

&lt;p&gt;Buk-ში ეს სამი ოპერაცია შემდეგნაირად გამოიხატება:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Look    დროებითი read access (მხოლოდ გამოყენება/წაკითხვა)

Change  დროებითი exclusive mutation (გადავცემთ ექსკლუზიურ წვდომას რათა გამომყენებელმა შეძლოს რესურსის მნიშვნელობის შეცვლა, მისი მუდმივი ფლობის გარეშე)

Take    (ექსკლუზიური მფლობელობის სამუდამო გადაცემა)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;კომპილატორი ამ ყველაფერს კომპილაციის დროს აკონტროლებს და ამოწმებს, რომ არც dangling reference შეიქმნას, არც უკვე გადაცემული მნიშვნელობა გამოვიყენოთ და არც conflicting access მოხდეს.&lt;/p&gt;

&lt;h2&gt;
  
  
  შესაბამისად, კიდევ ეღთხელ:
&lt;/h2&gt;

&lt;p&gt;Buk-ი იყენებს manual memory management-ს, Garbage Collector-ის გარეშე.&lt;/p&gt;

&lt;p&gt;Memory safety-ს კომპილატორი აკონტროლებს ownership და borrowing მოდელის საშუალებით. &lt;/p&gt;

&lt;p&gt;ყველა owning value-ს ჰყავს owner ("მფლობელი").&lt;/p&gt;

&lt;p&gt;კომპილატორი კომპილაციის დროს აკვირდება:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;სად შეიქმნა მნიშვნელობა&lt;/li&gt;
&lt;li&gt;ვინ ფლობს მას მოცემულ მომენტში&lt;/li&gt;
&lt;li&gt;სხვა ფუნქციას ownership გადაეცა თუ მხოლოდ დროებითი access / წვდომა&lt;/li&gt;
&lt;li&gt;ვის აქვს read access&lt;/li&gt;
&lt;li&gt;ვის აქვს mutation უფლება&lt;/li&gt;
&lt;li&gt;არსებობს თუ არა მის storage-ზე დამოკიდებული reference ან view &lt;/li&gt;
&lt;li&gt;როდის მთავრდება borrow-ის ბოლო რეალური გამოყენება&lt;/li&gt;
&lt;li&gt;შეიძლება თუ არა storage-ის invalidation ან გადაადგილება&lt;/li&gt;
&lt;li&gt;ვის ეკისრება საბოლოოდ რესურსზე და მის გათავისუფლებაზე პასუხისმგებლობა&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;მაგალითად:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GenerateSQL&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;GenerateTableMappings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ერთი შეხედვით ჩვეულებრივი კოდია. &lt;/p&gt;

&lt;p&gt;მაგრამ კომპილატორისთვის ამ ოთხ ხაზში სამი განსხვავებული ოპერაცია ხდება.&lt;/p&gt;




&lt;h1&gt;
  
  
  Look
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Look&lt;/strong&gt; ნიშნავს დროებით shared access-ს ownership-ის გადაცემის გარეშე.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="py"&gt;.Title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;LoadDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PrintSummary(document)&lt;/code&gt; არ ნიშნავს, რომ &lt;code&gt;Document&lt;/code&gt; დაკოპირდა.&lt;/p&gt;

&lt;p&gt;არც ownership გადასულა.&lt;/p&gt;

&lt;p&gt;ფუნქციამ უბრალოდ მიიღო დროებითი read access.&lt;br&gt;
ფუნქციის დასრულების შემდეგ &lt;code&gt;document&lt;/code&gt; ისევ გამომძახებელს ეკუთვნის.&lt;/p&gt;

&lt;p&gt;Buk-ში ყველაზე ხშირი ოპერაცია სწორედ Look-ია, ამიტომ ის საერთოდ არ იწერება.&lt;/p&gt;

&lt;p&gt;ანუ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;უკვე ნიშნავს read-only borrow-ს.&lt;/p&gt;

&lt;p&gt;არ გვჭირდება:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;look&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Change
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Change&lt;/strong&gt; ნიშნავს დროებით exclusive mutable access-ს.&lt;/p&gt;

&lt;p&gt;Ownership ისევ გამომძახებელს რჩება.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;IncreaseRevision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="py"&gt;.Revision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="py"&gt;.Revision&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;IncreaseRevision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;change&lt;/code&gt; დაახლოებით ასე შეიძლება წავიკითხოთ:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;„ეს მნიშვნელობა დროებით შენ გაბარია შესაცვლელად, მაგრამ ownership ჩემი რჩება.“&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;სანამ ასეთი borrow აქტიურია, კომპილატორი იმავე მნიშვნელობაზე conflicting access-ს არ დაუშვებს.&lt;/p&gt;

&lt;p&gt;როგორც კი &lt;code&gt;Change&lt;/code&gt; borrow-ის ბოლო რეალური გამოყენება დასრულდება, ორიგინალური მფლობელი მნიშვნელობას ჩვეულებრივად იყენებს.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;IncreaseRevision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;აქ mutation მომენტი კარგად ჩანს როგორც ფუნქციის დეკლარაციაში, ასევე გამოძახების დროსაც. &lt;/p&gt;

&lt;p&gt;ეს შეგნებულად ასეა.&lt;/p&gt;

&lt;p&gt;კოდის მკითხველმა ფუნქციის გამოძახების დანახვისას უნდა იცოდეს, რომ ამ გამოძახებას &lt;code&gt;document&lt;/code&gt;-ის შეცვლა შეუძლია.&lt;/p&gt;




&lt;h1&gt;
  
  
  Take
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Take&lt;/strong&gt; ownership-ის სრულ გადაცემას ნიშნავს.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ეს ფუნქცია ახლა ფლობს document-ის სრულ კონტროლს &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;LoadDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ამის შემდეგ ძველი მფლობელი ამ მნიშვნელობას (document-ს) ვეღარ გამოიყენებს:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// compile-time error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Runtime error არ ხდება.&lt;/p&gt;

&lt;p&gt;კომპილატორმა უკვე იცის, რომ &lt;code&gt;document&lt;/code&gt;-ის ownership გადავიდა Publish ფუნქციაში.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;take&lt;/code&gt; დაახლოებით ნიშნავს:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;„ამ მნიშვნელობის ownership მთლიანად შენ გადმოგეცი.“&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ეს განსაკუთრებით მნიშვნელოვანია რესურსებთან მუშაობისას, რადგან კომპილატორს ზუსტად შეუძლია იცოდეს, ვის ეკისრება კონკრეტულ resource-ზე საბოლოო პასუხისმგებლობა. პირობითად ოპერაციული სისტემის რომელიმე რესურსზე (პროცესი, HANDLE, სოკეტი ან სხვა). &lt;/p&gt;




&lt;h1&gt;
  
  
  Look, Change და Take ერთად
&lt;/h1&gt;

&lt;p&gt;ამიტომ ტიპური Buk-ის კოდი შეიძლება ასე გამოიყურებოდეს:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;LoadDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;Validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;PrintSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;აქ კომენტარები პრაქტიკულად არც არის საჭირო.&lt;/p&gt;

&lt;p&gt;ჩვეულებრივი გამოძახება ნიშნავს "ნახვას" / "გამოყენებას".&lt;/p&gt;

&lt;p&gt;&lt;code&gt;change&lt;/code&gt; ნიშნავს შეცვლას.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;take&lt;/code&gt; ნიშნავს ownership-ის გადაცემას.&lt;/p&gt;

&lt;p&gt;კოდში პირდაპირ ჩანს სრული სემანტიკა. &lt;/p&gt;




&lt;h1&gt;
  
  
  Buk vs Rust
&lt;/h1&gt;

&lt;p&gt;Rust-ში დაახლოებით იგივე მაგალითი ასე გამოიყურებოდა:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Buk-ში:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Inspect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;Inspect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ფუნდამენტური იდეა ორივეგან მსგავსია: ownership, shared borrow და exclusive mutable borrow.&lt;/p&gt;

&lt;p&gt;განსხვავება უფრო რეალიზაციის მოდელშია.&lt;/p&gt;

&lt;p&gt;Rust-ი კლასიკურ pointer/reference სემანტიკას იყენებს.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Buk-ი კი პროგრამისტის განზრახვას ძირითადად ოპერაციის დონეზე აჩვენებს:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Lifetimes
&lt;/h1&gt;

&lt;p&gt;Borrow Checker-ის მეორე მნიშვნელოვანი ნაწილი lifetimes-ია.&lt;/p&gt;

&lt;p&gt;თუ ფუნქცია მნიშვნელობას არ ფლობს და მხოლოდ "ნათხოვარი" აქვს (უჭირავს როგორც borrow), კომპილატორმა უნდა იცოდეს, რამდენ ხანს შეიძლება ამ borrow-ის გამოყენება და რომელ storage-ზეა დამოკიდებული.&lt;/p&gt;

&lt;p&gt;Rust lifetimes-ის უმეტესობას კომპილატორი თავისით ხვდება, მაგრამ ზოგიერთ უფრო კომპლექსურ კოდში Rust-ის კომპილატორს ჭირდება "ჰინტები" რაც კოდში უნდა დაიწეროს როგორც ფუნქციის დეკლარაციაში, ასევე გამოყენებულ ტიპებში. "'"-ის სახით. მაგალითად:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;pick&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Buk-ს public lifetime syntax საერთოდ არ აქვს.&lt;/p&gt;

&lt;p&gt;არ გვაქვს:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'a
'b
'static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;კომპილატორი თვითონ ადგენს, საიდან მოდის მნიშვნელობა და რაზეა მისი lifetime დამოკიდებული.&lt;/p&gt;

&lt;p&gt;მაგალითად:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;StringView&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="py"&gt;.Name&lt;/span&gt;&lt;span class="nf"&gt;.AsView&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;კომპილატორს შეუძლია დაადგინოს, რომ დაბრუნებული &lt;code&gt;StringView&lt;/code&gt; &lt;code&gt;user&lt;/code&gt;-ის backing storage-ზეა დამოკიდებული.&lt;/p&gt;

&lt;p&gt;პროგრამისტს ამის ხელით აღწერა არ სჭირდება.&lt;/p&gt;




&lt;h1&gt;
  
  
  მთავარი კომპილატორის მაგია. საიდან მოაქვს Buk-ს ინფორმაცია Lifetime-ების შესახებ, თუ კი კოდში არ ვწერთ "'"-ებს ?
&lt;/h1&gt;

&lt;p&gt;აქ ჩნდება &lt;strong&gt;&lt;code&gt;.bki&lt;/code&gt;&lt;/strong&gt;, ანუ Buk Package Interface.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.bki&lt;/code&gt; არის კომპლექსური მეტადატის შემცველი ფაილი, რომელსაც კომპილატორი აგენერირებს. &lt;/p&gt;

&lt;p&gt;მასში ინახება კოდის სემანტიკური კონტრაქტები. &lt;/p&gt;

&lt;p&gt;მაგალითად კომპილატორს შეიძლება დასჭირდეს ცოდნა იმის შესახებ, რომ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;დაბრუნებული მნიშვნელობის შენახვა ხდება რომელიღაც backing storage-ში (მაგალითად კოლექცია "UserList"-ის მეხსიერებაში)

ფუნქცია მხოლოდ კონკრეტულ ველს ცვლის

მნიშვნელობა await-ის იქით ვერ გადავა 

ფუნქცია ownership-ს იღებს
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ამ ინფორმაციის ნაწილი &lt;code&gt;.bki&lt;/code&gt;-ში ნორმალიზებული მეტადატის სახით გადადის. &lt;/p&gt;

&lt;p&gt;ამიტომ Buk-ის კომპილატორი და Borrow Checker-ი ფლობს სრულ სემანტიკურ ინფორმაციას პროგრამის შესახებ და ამის ხარჯზე შეგვიძლია უფრო მარტივი კოდი ვწეროთ. გარდა ამისა ბუკის კომპილატორს შეუძლია ბევრად მეტი ოპტიმიზაცია გააკეთოს ამ ინფორმაციაზე დაყრდნობით.&lt;/p&gt;




&lt;h1&gt;
  
  
  Explicit allocation
&lt;/h1&gt;

&lt;p&gt;Buk-ში მეხსიერების ალოკაციაც "ხელით" ხდება და სრულ კონტროლს გვაძლევს მეხსიერებაზე. Rust-ში ამის შესაძლებლობა არ გვაქვს და ხელით უნდა გაკეთდეს custom allocator.&lt;/p&gt;

&lt;p&gt;მაგალითად:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arena&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;in:&lt;/code&gt; ამბობს, სად უნდა შეიქმნას ახალი ownership და სად უნდა ჩაიწეროს ეს მნიშვნელობა. ამ შემთხვევაში გადაცემულ Arena-ში.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;StringView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Allocator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt; &lt;span class="n"&gt;fails&lt;/span&gt; &lt;span class="n"&gt;ParseError&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BuildDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;requestArena&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Async კოდი ფუნქციების coloring-ის გარეშე
&lt;/h1&gt;

&lt;p&gt;Buk-ის კიდევ ერთი მნიშვნელოვანი მიმართულება colorless async-ია.&lt;/p&gt;

&lt;p&gt;C#-ში, Rust-ში, Javascript-ში და სხვა ენებში async API შემდეგნაირად იწერება:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;LoadUserAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;ReadAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ფუნქცია სპეციალურ Task ტიპს აბრუნებს და გამოძახების მთელი ჯაჭვი უნდა იყოს async.  &lt;/p&gt;

&lt;p&gt;Buk-ში ფუნქცია სემანტიკურ მნიშვნელობას პირდაპირ აბრუნებს:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;LoadUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;fails&lt;/span&gt; &lt;span class="n"&gt;LoadError&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="nf"&gt;.Load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;ParseUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ფუნქცია&lt;code&gt;Future[User]&lt;/code&gt;, &lt;code&gt;Task[User]&lt;/code&gt; ან &lt;code&gt;Promise[User]&lt;/code&gt;-ს არ აბრუნებინებს.&lt;/p&gt;

&lt;p&gt;კომპილატორი თვითონ ადგენს ფუნქციის შესრულების ტიპს (ასინქრონულია თუ სინქრონული), გამოძახების მიხედვით. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;await&lt;/code&gt; მაინც უნდა დავწეროთ იქ სადაც ასინქრონულად გამოძახება ხდება.&lt;/p&gt;

&lt;p&gt;თუ ფუნქცია სინქრონულად სრულდება, კომპილატორი საერთოდ გააქრობს async scheduler-ს და state machine-ს და დაბილდავს როგორც უბრალო ფუნქციას. &lt;/p&gt;

&lt;p&gt;უფრო დეტალური ინფორმაცია ამის შესახებ გამოქვეყნდება ენის რელიზის დროს, თავის წიგნთან ერთად. &lt;/p&gt;

&lt;p&gt;ეს იყო მოკლე აღწერა. &lt;br&gt;
თავის მხრივ უფრო დეტალური აღწერა წიგნთან ერთად გამოვა რელიზის დროს, როგორც ზემოთ აღვნიშნე. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>security</category>
      <category>systems</category>
    </item>
    <item>
      <title>DLL injection of managed code into native process</title>
      <dc:creator>Rezo</dc:creator>
      <pubDate>Fri, 27 Dec 2024 10:47:21 +0000</pubDate>
      <link>https://dev.to/gervantofryvia/dll-injection-of-managed-code-into-native-process-3jo6</link>
      <guid>https://dev.to/gervantofryvia/dll-injection-of-managed-code-into-native-process-3jo6</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Getting started&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Project repository with full code is accessible on GitHub &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/RtlZeroMemory/Injector.C" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DLL injection is a powerful technique that allows us to inject custom code into a third-party process. It can be useful in various scenarios.&lt;/p&gt;

&lt;p&gt;DLL injection is often used by &lt;strong&gt;malware&lt;/strong&gt; to inject code into running processes, such as system processes like &lt;code&gt;svchost.exe&lt;/code&gt; or &lt;code&gt;explorer.exe&lt;/code&gt;, and execute malicious functionality within them.&lt;/p&gt;

&lt;p&gt;Malware usually resides inside existing process and acts as parasite to be harder to detect. It can use either DLL injection or full PE injection which is much more sophisticated method. &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Extending Program Functionality with DLL Injection&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DLL injection isn't just for malicious purposes—it can also be a legitimate tool for &lt;strong&gt;extending existing program functionality&lt;/strong&gt;. For example, you can use it to develop plugins for software.&lt;/p&gt;

&lt;p&gt;Imagine you want to &lt;strong&gt;log every action&lt;/strong&gt; that happens inside a process, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Network calls&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File system writes&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using &lt;strong&gt;function hooking&lt;/strong&gt;, you can intercept method calls within the process after injecting your DLL. &lt;/p&gt;

&lt;p&gt;Function hooking allows you to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intercept and monitor API calls&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modify input/output of functions&lt;/strong&gt; as needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extend a process's behavior&lt;/strong&gt; dynamically without modifying its source code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes DLL injection a versatile tool for developers, researchers, and security professionals alike.&lt;/p&gt;

&lt;p&gt;For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hook the &lt;code&gt;WriteFile&lt;/code&gt; function to capture details about file writes happening inside the process.&lt;/li&gt;
&lt;li&gt;Log this information for debugging, monitoring, or analysis.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;How WINAPI Works&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When a Windows process (PE - &lt;strong&gt;Portable Executable&lt;/strong&gt;) is started by the operating system's &lt;strong&gt;PE loader&lt;/strong&gt;, it loads all essential libraries required for the process into its address space.&lt;/p&gt;

&lt;p&gt;This includes libraries such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kernel32.dll&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ntdll.dll&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;user32.dll&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each Windows process can obtain access (&lt;strong&gt;HANDLE&lt;/strong&gt;) to libraries loaded into it using the &lt;code&gt;GetModuleHandle&lt;/code&gt; method. It can then retrieve individual methods using &lt;code&gt;GetProcAddress&lt;/code&gt; and call them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kernel32.dll&lt;/strong&gt;: Contains higher-level functions for tasks like memory management, file handling, and threading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ntdll.dll&lt;/strong&gt;: Contains lower-level counterparts, usually prefixed with "Nt", such as &lt;code&gt;NtQuerySystemInformation&lt;/code&gt;, which retrieves information about running processes in the operating system.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;The Flow of a WinAPI Call&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When you call a WinAPI function, control is passed to &lt;code&gt;ntdll.dll&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ntdll.dll&lt;/code&gt; uses a special routine like &lt;code&gt;KiFastSystemCall&lt;/code&gt; to pass control to the &lt;strong&gt;Windows kernel&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Inside the kernel, a lookup table called the &lt;strong&gt;System Service Dispatch Table (SSDT)&lt;/strong&gt; is used to locate the actual implementation of the function.&lt;/li&gt;
&lt;li&gt;The function executes in &lt;strong&gt;kernel mode&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Once complete, control is returned back to &lt;strong&gt;user mode&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How DLL Injection Works&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Steps to Inject a DLL&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open the Target Process&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Use &lt;code&gt;OpenProcess&lt;/code&gt; to get a handle to the target process with sufficient privileges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Allocate Memory in the Target Process&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Call &lt;code&gt;VirtualAllocEx&lt;/code&gt; to reserve space in the target process for the DLL path or custom code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write the DLL Path&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Use &lt;code&gt;WriteProcessMemory&lt;/code&gt; to copy the DLL path or custom code into the allocated memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Load the DLL&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Locate the address of &lt;code&gt;LoadLibraryA&lt;/code&gt; or &lt;code&gt;LoadLibraryW&lt;/code&gt; using &lt;code&gt;GetProcAddress&lt;/code&gt;, and then use &lt;code&gt;CreateRemoteThread&lt;/code&gt; to execute it in the target process. This loads the DLL into the process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Execute the DLL Code&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Once the DLL is loaded, its &lt;code&gt;DllMain&lt;/code&gt; function is called by the process's loader.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Happens After Injection&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Your DLL is &lt;strong&gt;loaded&lt;/strong&gt; into the target process's address space via &lt;code&gt;LoadLibrary&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Windows PE loader&lt;/strong&gt; calls your DLL’s &lt;code&gt;DllMain&lt;/code&gt; entry point.&lt;/li&gt;
&lt;li&gt;Any code in your DLL, such as hooks or logging, starts running &lt;strong&gt;in the context of the target process&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Full flow of this program&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Injects a native C library&lt;/strong&gt; into a native running process, such as &lt;code&gt;notepad.exe&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The injected library &lt;strong&gt;loads the CoreCLR runtime&lt;/strong&gt; into the target process.&lt;/li&gt;
&lt;li&gt;It then &lt;strong&gt;loads a managed C# DLL&lt;/strong&gt; into the process's address space and calls its entry point method (&lt;code&gt;Main&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The C# DLL &lt;strong&gt;executes within the unmanaged process&lt;/strong&gt; and calls the &lt;code&gt;MessageBox&lt;/code&gt; function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This DLL outputs current process information in a MessageBox after being injected into native process, in this case notepad. &lt;/p&gt;

&lt;p&gt;After starting injector end result looks like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvawebqsxfgz415s3om4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvawebqsxfgz415s3om4n.png" alt="Image description" width="800" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frn6u54k1ojg94gpx11hz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frn6u54k1ojg94gpx11hz.png" alt="Image description" width="316" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NOTES:&lt;/p&gt;

&lt;p&gt;To run this example you can clone repository and edit source code to include correct path to CoreCLR and injected library inside source code. Right now everything is hardcoded. &lt;br&gt;
Code for injected DLL:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
csharp
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace InjectLib.Managed
{
    public static class InjectLibManaged
    {
        const uint MB_OK = 0x00000000;
        const uint MB_ICONFIRMATION = 0x00000040; 

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);

        public static void Main()
        {
            var proc = Process.GetCurrentProcess();
            MessageBox(
                IntPtr.Zero,
                $"Hello from Process with Id: {proc.Id}, {proc.ProcessName}",
                "Hello from injected DLL",
                MB_OK | MB_ICONFIRMATION
            );

            Thread.Sleep(50000);
        }
    }
}



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>net</category>
      <category>winapi</category>
      <category>cybersecurity</category>
      <category>dllinjection</category>
    </item>
  </channel>
</rss>
