LARA

Dynamic Method Dispatch in Object-Oriented Languages

How do we know which method is invoked here in the following:

var x : Object;
println(x.toString())

The invoked method depends on the dynamic type of 'x'.

We can view the method to execute as a field of function type

Simple implementation: store function pointers in the object

  • if a class has 100 methods, each object of this class would have 100 fields

All objects of same class have same code pointers for methods

  • introduce a table for each dynamic type, Virtual method table (vtable)
  • dynamic type of object give a pointer to corresponding vtable

How can we call methods in supertypes?

  • for single inheritance, we arrange methods in sequence, from superclass to subclass
  • superclasses ignore entries from subclass

Code Showing Dynamic Dispatch

class Dialog {
  var title : String = _
  def show = {
    println("[" + title + "]")
  }
  def showTwice = {
    show
    show
  }
}
 
class FancyDialog extends Dialog {
  var howFancy = "!!!"
  override def show = {
    println(title + howFancy)
  }
  def star = { 
    title = title + "*"
  }
}
 
object Test extends Application {
  var x = new Dialog
  x.title = "D"
  x.show
 
  var y = new FancyDialog
  y.title = "FAD"
  y.show
  y.star
 
  x = y
  x.showTwice
}

What output does this give?

Sketch of Compiled Code for Dynamic Dispatch

// Dialog ----------------------------------
 
def makeDialogObject = {
  new Array(
    0 -> DialogVtable // offset 0 is vtable
    4 -> _            // offset 4 is pointer to 'title' string
}
 
def Dialog.show = {
  println("[" + this(4) + "]")
}
 
def Dialog.showTwice = {
  this(0).     // get vtable
          (0)  // invoke show pocedure (first declared)
  this(0).     // once again 
          (0)  
}
 
val DialogVTable = 
  new Array(
    0 -> Dialog.show 
    1 -> Dialog.showTwice 
 )
 
// FancyDialog ----------------------------
 
def makeFancyDialogObject = {
  new Array(
    0 -> FancyDialogVTable // vtable
    4 -> _                 // 'title', same position as in makeDialogObject
    8 -> "!!!"             // 'howFancy' string 
}
 
def FancyDialog.show = {
  println(this(4) + this(8)
}
 
def FancyDialog.star = {
  this(4) = this(4) + "*"
}    
 
val FancyDialogVTable = 
  new Array(
    0 -> FancyDialog.show // overriding Dialog.show
    4 -> Dialog.showTwice // remains same
    8 -> FancyDialog.star // subclass method
 )
 
// main
 
var x = makeDialogObject
x(4) = "D" // title
x(0).(0)   // show
 
var y = makeFancyDialogObject
y(4) = "FAD" // title
y(0).(0)     // show
y(0).(8)     // star
 
x = y
x(0).(4)     // showTwice