How uvm phasing mechanism (behind the curtain) work ? can it be achived by systemverilog features?

In UVM we directly use phases to do different things. But how simulator understands from uvm base library that it need to start with build_phase and after that need to execute connect_phase and so on …

Till now I just got this info but don’t understand how it actually works. Could anyone help me understand summarizing underlying mechanism ?

https://verificationacademy.com/verification-methodology-reference/uvm/docs_1.1c/html/files/base/uvm_phase-svh.html#uvm_phase

In reply to vickydhudashia:

The simulator understands UVM because ir is written in SystemVerilog. The phasing is taking advantage of virtual methods and building lists of “Component” classes and simply iterating over that list for each phase. Below is a very simplified example showing the structures the UVM creates and how it executes them:

class Component;
  string m_name;
  Component m_parent;
  static Component list[$];
  function new(string name, Component parent);
    m_name = name;
    m_parent = parent;
    list.push_back(this);
  endfunction
  function string get_fullname;
    if (m_parent == null)
      return m_name;
    else
      return {m_parent.get_fullname(), "." , m_name};
  endfunction         
  virtual function void build_phase;
  endfunction 
  virtual task run_phase;
  endtask 
  virtual function void report_phase();
  endfunction 
endclass 
class A extends Component;
  function new(string name, Component parent);
      super.new(name,parent);
     $display("A Constructing: ", get_fullname);
   endfunction
   task run_phase;  
     #10  $display("Running   from ",get_fullname(),,$time);
   endtask
   function void report_phase;
          $display("Reporting from ",get_fullname(),,$time);
   endfunction
  
endclass 
class B extends Component;
  function new(string name, Component parent);
   super.new(name,parent);
   $display("B Constructing: ", get_fullname);
  endfunction
  A a;
  function void build_phase;
    a = new("a",this);
  endfunction
  task run_phase;  
    #20  $display("Running   from ",get_fullname(),,$time);
  endtask
endclass 
class Root extends Component;
  function new(string name, Component parent);
    super.new(name,parent);
    $display("env Constructing: ", get_fullname);
   endfunction
  A a;
  B b;
  function void build_phase;
    a = new("a",this);
    b = new("b",this);
  endfunction
  task run_test;
    // build_phase
    for(int item=0;item<list.size();item++)
      list[item].build_phase();
    // run_phase 
    foreach(list[item])
      fork
        int k = item;
        list[k].run_phase();
      join_none
    wait fork;
    // report phase
    foreach(list[item])
      list[item].report_phase();
      endtask
endclass

module top;
   Root root;
   initial begin
     root =new("root",null);
     root.run_test();
   end
endmodule