Document

Object-oriented Languages
Compiler
Baojian Hua
[email protected]
OOP

So far, we’ve covered most C features


Object-oriented languages are more and
more popular due to the industry push


expression, statement, function
this time: compile the class-based OO lang’
Roadmap:




class and objects
inheritance & virtual functions
RTTI & reflection
next time: exception
Class “Point”
class P2
{
int x;
int y;
P2 (int x, int y) {
this.x = x;
this.y = y;
}
void print () {
println (this.x, this.y);
}
}
Compiling to C
// Close all functions:
class P2
{
int x;
int y;
P2 (P2 this, int x, int y) {
this.x = x;
this.y = y;
}
void print (P2 this) {
println (this.x, this.y);
}
}
Compiling to C
// Hoisting:
class P2
{
int x;
int y;
}
P2 (P2 this, int x, int y) {
this.x = x;
this.y = y;
}
void print (P2 this) {
println (this.x, this.y);
}
Compiling to C
// In C’s syntax:
struct P2
{
int x;
int y;
};
typedef struct P2 *P2;
P2 (P2 this, int x, int y)
{
this->x = x;
this->y = y;
}
P2
x
y
Client Code
// Client code:
P2 p = new P2 (3, 4);
p.print ();
// compiles to:
P2 p = malloc (sizeof (*p));
P2(p, 3, 4);
print(p);
P2
x
y
Moral

Difference with C?



In history, some compilers compile OO to C


class = struct + function code
object = a region of memory in mem (malloc?)
e.g., Bjarne Stroustrup et.al’s Cfront
But how does this work with other features?


inheritance
dynamic dispatch
Inheritance
// Single inheritance:
class P3 extends P2
{
int z;
P3 (int x, int y, int z) {…}
// Note: this is not named “print”. Why?
void print3d () {
println (this.x, this.y, this.z);
}
}
Prefixing
// A technique called prefixing:
class P3 extends P2
{
int x;
int y;
int z;
void print () {
…
}
void print3d () {
…
}
}
Compiling to C
struct P2
{
int x;
int y;
};
struct P3
{
int x;
int y;
int z;
};
P2
x
y
P3
void P2_print (P2 this) {…}
void P3_print (P2 this) {…}
void print3d (P3 this) {…}
x
y
z
Q: can we
put “z”
before “x” or
“y”?
Virtual functions
class P2
{
…;
void print () {…}
}
class P3 extends P2
{
…;
void print () {…}
}
Dynamic dispatch
class P2
{
…;
void print () {…}
}
class P3 extends P2
{
…;
void print () {…}
}
P2 p;
p = new P2 ();
p.print ();
p = new P3 ();
p.print ();
Compiling dynamic dispatch




Variable’s compile-time type is insufficient to
determine the specific function to be called
We need store in the object the information
required
The data structure for this purpose is the
famous virtual function table or vtable
Function call becomes an indirection via
vtable
Vtable
class P2
{
…;
void print ()
{…}
}
vptr
x
y
vptr
class P3 extends P2
{
…;
void print ()
{…}
}
P2_print
x
y
z
P3_print
General Scheme
class A
{
int x1;
…;
int xn;
vptr
x1
…
xn
A_f1
…
A_fn
vtable
void f1 (…){}
…
void fn (…){}
};
Client Code
// Client code:
P2 p;
p = new P2 (3, 4);
p.print ();
vptr
x
P2_print
y
p
// compiles to:
P2 p;
p = malloc (sizeof (*p)); // how many bytes?
P2(p, 3, 4);
((p->vptr)[0]) (p);
// where’s “print”?
Client Code
// Client code:
P2 p;
p = new P2 (3, 4);
p.print ();
p = new P3 (7, 8, 9);
p
p.print ();
vptr
7
8
9
vptr
P2_print
x
y
P3_print
Moral

Dynamic dispatch is polymorphism:


subtyping poly’
No free lunch:



extra space to store vtable
dynamic dispatch via indirection (slow?)
“All problems in computer science can be solved
by another level of indirection!”


-- Butler Lampson
OO = Pointer + Virtual Functions
RTTI & reflection

RTTI: Run Time Type Identification


Reflection:


Ability to identify the type (class) of an object at runtime
more powerful, can (mostly) do anything at runtime
What are they used for?





Type identification
Inheritance hierarchy
string based method invocation
exception handling
…
RTTI
P2 p;
…;
Class c = p.getClass ();
println (c.getClassName());
vptr
x
y
meta
name
P2_print
…
…
“P2”
Reflection
P2 p;
…;
Class c = p.getClass ();
println (c.getClassName());
c.getMethod (“print”, null);
vptr
x
y
meta
name
P2_print
“print”, p
…
“P2”
Case study:
Visual studio C++ (Microsoft)
Multiple Inheritance
Template