C# Classes Translation
Program Class
Each to-be-translated C# file should comply with the following rules:
- A class with Program methods must be marked with a
[Program]
attribute. - Each compiled .exe file must contain exactly one class with a
[Program]
attribute. - A Program class can inherit interfaces [future plans]
- A Program class only contains public fields and public or private methods.
- Static fields and methods are not allowed.
- Public methods are translated to Program methods.
- Private methods are translated to inner functions, the only difference from Program methods being that the inner functions are not accessible from the outside world and can only be called from a Program method.
- Fields (that can be only public) are translated to storage items with
utf8("p_<field_name>")
keys. - Only one Program class constructor is allowed. This constructor must not have any arguments.
User Defined Classes
Users can freely define classes without a [Program]
attribute. Objects of these classes are translated to data struct
s and behave very similar to objects in C#.
Formally, this translation follows these rules:
- A class doesn't have a
[Program]
attribute, the[Program]
attribute is only used for one class, which is translated to Program methods. - Interfaces are not translated, they only serve as compile-time entities.
- All (
private
,protected
,internal
andpublic
) fields are translated toutf8("<field_name>") -> <field_value>
pairs instruct
. - All methods are translated to
utf8("<method_name>_<args_types>")
->ref(#<inner_function_offset>)
. The<args_types>
prefix is needed to support overloading and<inner_function_offset>
means the offset of the function that should be called for the<method_name>
method of that class. Overridden methods will point to different<inner_function_offset>
. This technique is similar to Virtual method table. static
fields are translated to storage items withutf8("s_<class_name>_<field_name>")
keys.static
methods are translated to inner functions with<class_name>_<method_name>_<args_types>
names.- Constructors are translated to inner functions with
<class_name>_ctor_<args_types>
names.
Example:
Let’s assume that we have the following classes definitions in C#:
interface Vehicle
{
void ComeIn(String someone);
}
class Bicycle : Vehicle
{
public String Owner = "no one";
void ComeIn(String someone) {
Owner = someone;
}
}
class Car : Vehicle
{
static private bool isBearBurnedDown = false;
static public bool IsBearBurnedDown()
{
return Car.isBearBurnedDown;
}
public int NumberOfTires;
public Car(int tires)
{
NumberOfTires = tires.
}
void ComeIn(String someone)
{
if (someone == "bear") {
Car.isBearBurnedDown = true;
}
}
}
interface Vehicle
won't be translated to anythingBicycle()
constructor will be translated to theBicycle_ctor
function that createsstruct(utf8("Owner") -> utf8("no one"), utf8("ComeIn_string") -> ref(#<function1>)
Bicycle.ComeIn
will be translated to a certain function (let's call itfunction1
) that changes theutf8("Owner")
field in the givenstruct
.Car(int)
constructor will be translated to theCar_ctor_int32
function that createsstruct(utf8("NumberOfTires") -> int32(<given_int>), utf8("ComeIn_string") -> ref(#<function2>))
isBearBurnedDown
static field will be translated toutf8("s_Car_isBearBurnedDown") -> bool
storage item.IsBearBurnedDown
static method will be translated toCar_IsBearBurnedDown
function that readsutf8("s_Car_isBearBurnedDown")
storage key.Car.ComeIn
will be translated to a certain function (let's call itfunction2
) that changesutf8("s_Car_isBearBurnedDown") -> bool
storage item according to the givenString
from the stack.