Pages

Friday 7 September 2012

computer language ကိုယ္ပိုင္တီထြင္ျခင္း +7

Function Support (ေနာက္ဆက္တြဲ)

Note: ေရွ႕က Function Support Chapter ဟာေရးရင္းနဲ႔ ရွည္သြားတဲ့အတြက္ ျဖတ္လိုက္ရတာပါ။ တကယ္ေတာ့ function နဲ႔ပတ္သက္ၿပီးနဲနဲ ေျပာစရာက်န္ပါေသးတယ္။ ဒါေၾကာင့္ ဒီ chapter ကိုဆက္လိုက္ရပါတယ္။

Virtual Function

ေအာက္က C code ကိုၾကည့္ပါ။
typedef void (*FuncPointer)(int param);
void MyFunc(int param) {
}
FuncPointer foo = MyFunc;
foo( 10 );
ဒီေနရာမွာ FuncPointer က function pointer type ပါ။ C မွာ function ရဲ႔ address ကိုဒီလိုပဲ pass လုပ္ၿပီး ေခၚလို႔ရတယ္။ ဒါေပမဲ့ ကၽြန္ေတာ္တို႔ Language မွာေခၚလို႔မရေသးဘူး။ ဘာေၾကာင့္လဲဆိုေတာ့ function ရဲ႔ address ကို operand ေန pass လုပ္ေပးလိုက္လို႔။ ဒီအတြက္ function ရဲ႔ address ကို stack ေပၚကေန ယူရင္ အေပၚက C code လိုေရးလို႔ရၿပီ။ ရွိၿပီးသား OP_CALL ကိုမျပင္ေတာ့ဘဲ ဒီအတြက္ op-code အသစ္ထပ္ေရးရေအာင္။ သူ႕ကိုေတာ့ virtual_call လို႔ေခၚပါမယ္။ ဒါမွ static function ကိုေခၚခ်င္ရင္ ပို efficient ျဖစ္တဲ့ call ကိုသုံးၿပီး dynamic function ေတြအတြက္ virtual_call ကိုသုံးၾကတာေပါ့။ Virtual call op-code အသစ္ကိုသြားေၾကညာပါ။
enum OpCode {
 OP_TALK,
 ..........................
 ..........................
 OP_VIRTUAL_CALL,
 OP_END
};
ၿပီးရင္ virtual call အတြက္ Virtual Machine ရဲ႔ Run() function မွာသြားေရးပါ။
void Run(Program& program) {
 while (true)
 {
  Instruction inst = program.Next();
  switch (inst.code)
  {
  ....................
  ....................
  case OP_VIRTUAL_CALL:
  {
   int FuncAddress = program.PopStack();
   program.PushStack( program.GetCurrentInstruction() );
   program.SetInstruction( FuncAddress );
   break;
  }
  ....................
  ....................
  }
 }
}
ဘာမွေထြေထြထူးထူးမဟုတ္ပါဘူး။ Call ထဲကအတိုင္းေရးထားပါတယ္။ ဒါေပမဲ့ function address ကို operand 0 ကေနမယူဘဲ stack ေပၚက pop လုပ္ယူလိုက္ပါတယ္။ ၿပီးရင္ Assembly code table ထဲပို virtual_call အတြက္ entry အသစ္သြားထည့္ပါအုံး။ ဒါမွ assembler က compile လုပ္လို႔ရမွာေလ။
အရင္ chapter က function စမ္းတဲ့ code ကို virtual call သုံးၿပီး ေရးၾကည့္ရေအာင္ပါ။
000 put_stack 10
001 put_stack 5
002 scope 2
003 put_stack 13
004 virtual_call  
005 num
006 put_stack 45
007 put_stack 32
008 scope 2
009 put_stack 13
010 virtual_call
011 num
012 end
// function A()
013 get_scope 0
014 get_scope 1
015 add
016 return
ဒီ assembly code မွာ function address ကို operand ေနမေပးဘဲ stack ေပၚကေန pass လုပ္ေပးလိုက္ပါတယ္။ ဒါဆို function address ကိုသိမ္းခ်င္တဲ့ ေနရာမွာသိမ္း၊ ၿပီးရင္ stack ေပၚကို Push လုပ္တင္၊ ၿပီးရင္ virtual call နဲ႔ေခၚလိုက္ရုံပါဘဲ။
ခုကၽြန္ေတာ္တို႕ language မွာ function ကို static ေကာ dynamic ေကာေခၚလို႔ရေနပါၿပီ။ Dynamic function ေတြဟာ Object Oriented Programming ထဲက polymorphism အတြက္လဲ အေရးပါပါတယ္။ ဘာေၾကာင့္လဲဆိုရင္ polymorphism ဟာလဲ virtual table လို႔ေခၚတဲ့ function pointer ေတြသိမ္းထားတဲ့ table နဲ႔ အလုပ္လုပ္တာပါ။ ဒီလို function pointer ကို dynamically ေခၚတာဟာ၊ ရိုးရိုး function ကို static ေခၚတာေလာက္ efficient မျဖစ္ဘူးဆိုတာ လက္ေတြ႕ ေတြ႕ၿပီမဟုတ္လား (ကၽြန္ေတာ္တို႔ language မွာဆို push_stack တခုပိုတယ္ေလ)။ ဒါေၾကာင့္ C++ လို programming ေတြမွာ virtual keyword ကို တကယ္လိုအပ္တဲ့ member function ေတြမွာသာေပးသင့္ပါတယ္။ မလိုအပ္ရင္ (polymorphism အရ overwrite မလုပ္ရင္) static function အေနနဲ႔ေခၚတာဟာ ပိုၿပီး efficient ျဖစ္ၿပီး ျမန္ေစပါတယ္။

Why Inline Function?

ဒီေနရာမွာ inline function အေၾကာင္းပါဆက္ ေျပာခ်င္ပါတယ္။ Function တခုကို call လုပ္ရင္ သူ႔ထဲမွာေရးထားတဲ့ code ေတြတင္အလုပ္လုပ္တာ မဟုတ္ပါဘူး။ call ကိုမေခၚခင္ parameter ေတြနဲ႔ local variable ေတြကို stack ေပၚကိုတင္ရပါမယ္။ ၿပီးရင္ scope သတ္မွတ္ရပါမယ္။ ဒီအတြက္ scope offset နဲ႔ scope size ေတြကိုလဲ stack ေပၚသြားသိမ္းရပါမယ္။ processing လုပ္ရသလို၊ stack size လဲကုန္ပါတယ္။ Return ျပန္ရင္လဲ stack ေပၚတင္ထားသမွ်ျပန္ pop လုပ္ရပါမယ္။ ဒါ function တခုေခၚဖို႔အတြက္ လုပ္ေဆာင္ခ်က္ေတြပါ။
တကယ္လို႔ function ထဲက code ကနဲနဲေလးဆိုရင္ coding ကို run ရတာထက္ function ေခၚဖို႔ prepare လုပ္ရတာ ပိုေနပါလိမ့္မယ္။

 ေပၚ့ေစလိုလို႔ ေၾကာင္ရုပ္ထိုး ေဆးအတြက္ေလး ဆိုတဲ့ စကားပုံလို ျဖစ္ေနပါတယ္ :) ဒီအတြက္ solution ကေတာ့ code ေတြကို function ထဲမထည့္ဘဲ တိုက္ရိုက္ေရးျခင္းပါ။ C လို High-level language ေတြမွာေတာ့ Inline Function လုပ္လိုက္ရင္ အဲဒီ function က တကယ့္ function မဟုတ္ေတာ့ဘဲ compiler က function ထဲက code ေတြကို ေခၚတဲ့ေနရာမွာဘဲ တိုက္ရုိက္ေရးပါတယ္။ ဒီအတြက္ ေစာေစာက ေျပာတဲ့ function ေခၚဖို႔ prepare လုပ္ရတဲ့ အဆင့္ေတြမရွိေတာ့ပါဘူး။ ကၽြန္ေတာ္တို႕ assembly language မွာေတာ့ ဒီလို luxury မ်ိဳးမရွိတဲ့အတြက္ လူကိုယ္တိုင္ကဘဲ code ေတြကို တိုက္ရိုက္ေရး ရပါေတာ့မယ္။

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...

အေထြးေထြးနည္းပညာမ်ား