ccc : user defined object structure in c yasunori harada / jst and ntt kenichi yamazaki / ntt docomo...
TRANSCRIPT
CCC : User Defined Object Structure in C
Yasunori Harada / JST and NTT
Kenichi Yamazaki / NTT Docomo
Richard Potter / JST
Outline
• Motivation for CCC
• CCC Language Features
• Implementation of CCC
• Discussion
Inflexibility of Traditional OOPLs
e.g., C++ requires all objects have a pointer to a virtual function table
good point•fast method dispatching
bad points•extra memory•incompatible for some data struct
object
virtual function table
objectobject
OOPL Incompatible Data Structures
• low-level data– ex. very compact object implementation
tag-embedded pointers
• external data– standard data structure
• file structures• network packet structures• XWindow XEvent structure
object ID
object pointer class ID
....
file structure
Current OOPLs cannot treat them as objects.
Implicit Classes
Such non-oopl compatible data can still be though of in terms of classes, ex.– a tag-embedded pointer p is a CONS if
p != 0 && (p & 0x6) == 0
– a file f is a GIF format if
(f[0]==’G’) && (f[1]==’I’) && ...
Brute Force Polymorphism
void method (...) { if (check class A ...) { if (check class B ...) { class B’s method } else { class A’s method } } else if (check class C ...) { class C’s method }}
Such implicit classes often appear as old fashioned programming that uses a condition hierarchy.
A C
B
Simple Idea
• Define a class by a condition – like Cecil, Predicate Dispatching
• Allow class to take arguments, but no instance variables
• Use a language processor– inputs class/method definitions– outputs old-fashioned dispatch functions
CCC (C with Condition Classes)
• Small C extension (C preprocessor)
• Treating arbitrary data as an object
• A class is defined by a C condition
Class Definition
class-name : identifier
class-arguments : a sequence of type/variable pairs
condition : C expression
class-body : sub-class, method and macro definitions
@class class-name {(class-arguments)} {if (condition)} { class-body
}
Example
@class data(int *array, int idx) { @class line if (array[idx] == `L`) { void draw(Window w) { ... } } @class rect if (array[idx] == `R`) { void draw(Window w) { ... } }}
L
R
...
50
3050
20
10
array
idx
Special encoded objects in an array
CCC’s Output of the Example
void draw(int *array, int idx, Window w) { if (array[idx] == `L`) { ... return; } if (array[idx] == `R`) { ... return; }}
Class Local Macro
@class line if (array[idx] == `L`) { macro X1 {array[idx+1]} macro Y1 {array[idx+2]} ... void draw(Window w) { draw_line(w, X1, Y1, ...); } void dmove(int dx, int dy) { X1 += dx; .... }}
L
R
...
50
3050
20
10
array
idx
X1
Y1
Three Condition Types
To generate an efficient dispatch function, the programmer controls condition types
• if– (fast, but dangerous)
• elsif– for overlapped conditions (most general)
• switch-case– for dispatching by constants (fastest)
typedef unsigned int ptr;@class object (ptr self) switch (self & 0x6) {
@class list case (0x0) { @class nil if (self == 0) { } @class cons elsif (1) { } }
@class number case (0x2) { }
@class string case (0x4) { } ...}
Example
00
11
01
10
Example of Methods and Macros
@+object { ptr car() { return 0; } ptr cdr() { return 0; }}@+cons { macro CAR {(*((ptr *)self))} macro CDR {(*((ptr *)self+1))} ptr car() { return CAR; } ptr cdr() { return CDR; }}
self
CAR CDR
CCC’s Output of the Exampleptr object_car(ptr self) { return 0; }ptr cons_car(ptr self) { return (*((ptr *)self)); }
ptr car(ptr self) { switch (self & 0x6) { case (0): if (self == 0x0) { } else if (1) { return cons_car(self); } default: return object_car(self); }}
CCC Implementation
Generating Dispatch Functions
• Step 1 - Create single class tree from all CCC files
• Step 2 - For each unique method signature, extract a method tree from the class tree
• Step 3 - Generate dispatch function for each method tree
Class Tree
class arguments
C1
C3C4C2
C5
C1,C2, ..: condition
: class
: method
Extracting Method Trees
• If a class L defines the method M, then L is in T.
• If a class L’s subclass is in T, then L is in T.
• If an elsif-class L is in T, then L’s elder sibling classes are in T.
C1
C3C4C2
C5
C1
C4C2
C5
T
Generating Dispatch Function method { if (C1) { if (C2) { if (C5) { ; return; } } if (C4) { ; return; } ; return;} }
C1
C4C2
C5
Discussion
User-level Class
@+cons { @class point (CAR == pointSymbol) { }}@+point { void print() { print(car(CDR)); printstr(”@”); print(car(cdr(CDR))); }} (point 20 30) 20@30
Overlapped Conditions
@class A (int x) { @class B if (x > 100) { } @class C if (x > 0) { }}
@class A (int x) { @class B if (x > 100) { } @class C elsif (x > 0) { }}
Class A and C have a method M
void M(int x, ..) { if (1) { if (x > 0) { C_M(x, ..); return; } A_M(x, ..); return;} }
void M(int x, ..) { if (1) { if (x > 100) { } else if (x > 0) { C_M(x, ..); return; } A_M(x, ..); return;} }
Exclusive Conditions
@class A (int x) { @class B if (x < 100) { } @class C if (x > 0) { }}
@class A (int x) { @class B if (x < 100) { } @class C elsif (x > 0) { }}
Class A and C have a method M
void M(int x, ..) { if (1) { if (x > 0) { C_M(x, ..); return; } A_M(x, ..); return;} }
void M(int x, ..) { if (1) { if (x < 100) { } else if (x > 0) { C_M(x, ..); return; } A_M(x, ..); return;} }
C++ for back-end
• CCC can generate C++ code too.
• It changes how method signatures are treated– C++ includes arguments and reply type– this allows increased program modularity
CCC Implementation
• 2500 line C program • source code debugging using #line directive for
C compiler• reads several CCC sources and generates one large
C or C++ code
Related Work
• Cecil[Chambers 92], Predicate Dispatching[Ernst 98]– a method is defined by a predicate– a Cecil object has an internal structure.
• e language [Hollander 01]– for hardware testing– combining constraint-oriented and oo
• EU-lisp[Queinnec 88], SchemeXerox [Adams 93]– how to use low-level data in lisp-like language
CCC Programming Model
Data Space
CCC Programming Model
Data Space
interpretation(class hierarchy)
CCC Programming Model
Data Space
interpretation(class hierarchy)
methods
CCC Programming Model
Data Space
interpretation(class hierarchy)
interpretation(class hierarchy)
methodsmethods
Future Work
Separate Compilation
• Current CCC implementation does not support separate compilation– CCC generates a single large file.
• Idea– generate files for each unique method signature– CCC does not touch a file if its method is
unchanged– the back-end compiler uses the previous
compile result for an unchanged method
Reducing redundant checks
a = car(p); d = cdr(p);inefficient!
Reducing redundant checks
a = car(p); d = cdr(p);inefficient!
with (p) { a = car(); d = cdr();}
Reducing redundant checks
if ( check cons ) { a = cons_car(p); d = cons_cdr(p);} else { a = object_car(p); d = object_cdr(p);}
a = car(p); d = cdr(p);inefficient!
with (p) { a = car(); d = cdr();}
Conclusion
• CCC can treat arbitrary data as an object• A class is defined by a condition as in Cecil.• Class local macros instead of instance
variables• CCC has no encapsulation
– can treat external data as an object.– can attach multiple class hierarchy onto the same
data.