Difference between revisions of "Dynamic Binding"

m (Dynamic binding in finalized code)
m (Dynamic binding in finalized code)
Line 46: Line 46:
  
 
====Dynamic binding in finalized code====
 
====Dynamic binding in finalized code====
In finalized code the dynamic binding is very simple. For every routine_id there exists an array, that maps dynamic type ids to function pointers. The code snipped how the dynamic binding works:  
+
In finalized code the dynamic binding is very simple. For every routine_id there exists an array, that maps dynamic type ids to function pointers.  
 +
 
 +
For an example the ABC system is used including the assumption that the system contains the two type instantiations C [STRING] and C [INTEGER]. This could result in the following type_id's:
 +
*50 for A [INTEGER]
 +
*51 for A [STRING]
 +
*52 for B [INTEGER]
 +
*53 for B [STRING]
 +
*54 for C [INTEGER]
 +
*55 for C [STRING]
 +
 
 +
The code snipped how the dynamic binding works:  
  
 
{|border="0" cellpadding="2" cellspacing="0" align="center"
 
{|border="0" cellpadding="2" cellspacing="0" align="center"

Revision as of 13:15, 10 January 2007

Warning.png Warning: Warning: Article under development

Dynamic binding is a key feature behind object technology. In the following piece of code:

foo (a: A)
   do
      a.f
   end

It is not known at compile time, which feature has to be called for call a.f. This depends on the exact type of the object referenced by a, also called its dynamic type.

Talking about ids: Routine_id, body_id, real_body_id, feature_id, class_id and type_id

In a compiled Eiffel system, every feature that is a seed gets its own unique routine_id. Features that are just inherited or are a redeclaration have the same routine_id as their precursor (See Routine IDs). It is possible for a feature to have more than one routine_id when it has more than one precursor.

Every routine body, that means every declaration or redeclaration, gets its own unique body_id.

Every feature of a class gets a feature_id that is unique in the context of this class.

In the following picture it is shown how these ids could look like:

DynamicBindingABCExample.jpg

The body_id of feature g in A and B are the same since g is not redefined in B. As it will be shown later, the chosen routine_id have an impact on the dynamic binding semantics. In class C the feature f_b gets the routine_id 1 since it is selected, the not selected feature f of C gets a new routine_id.

Feature j of class C that redefines both feature g of A and feature h of B gets both their routine_id's.

Every class gets a unique class_id an every type a unique type_id. A body of a generic class may need several translated versions, when there are different type instantiations of the class. For getting the right version of the correct type instantiation the real_body_id is used.

To sum up, the following ids were introduced:

  • routine_id
  • body_id
  • feature_id
  • real_body_id
  • class_id
  • type_id

Dynamic binding in finalized code

In finalized code the dynamic binding is very simple. For every routine_id there exists an array, that maps dynamic type ids to function pointers.

For an example the ABC system is used including the assumption that the system contains the two type instantiations C [STRING] and C [INTEGER]. This could result in the following type_id's:

  • 50 for A [INTEGER]
  • 51 for A [STRING]
  • 52 for B [INTEGER]
  • 53 for B [STRING]
  • 54 for C [INTEGER]
  • 55 for C [STRING]

The code snipped how the dynamic binding works:

char *(*Txiockf[6])();
void Txiockf_init () {
   // A [INTEGER] has type_id 50
   Txiockf[0] = (char *(*)()) Fcuus0f;
   // B [INTEGER] has type_id 50
   Txiockf[1] = (char *(*)()) Fcuus0g;
   // C [INTEGER] has type_id 50
   Txiockf[2] = (char *(*)()) Fcuwquc;
   Txiockf[3] = (char *(*)()) Fcuwque;
   Txiockf[4] = (char *(*)()) Fcuwquc;
   Txiockf[5] = (char *(*)()) Fcuwque;
}
void Fcubdx0 (EIF_REFERENCE Current, EIF_REFERENCE arg1) {
   ...
   (FUNCTION_CAST(void, (EIF_REFERENCE)) 
      Txiockf[Dtype(arg1)-50])(arg1);
   ...
}


In this example the type_id for A body_id refers to a certain body of a class. The real_body_id refers a body of one specific generic derivation of a class. The real_body_id is very important in workbench mode. Once the real_body_id is resolved for a call, the rest is just melting ice stuff. In the call to a.f the routine_id of f is known.