annotate dmd/BaseClass.d @ 4:d706d958e4e8

Step 2 of restoring GC functionality.
author korDen
date Mon, 26 Oct 2009 16:28:19 +0300
parents 7427ded8caf7
children e28b18c23469
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1 module dmd.BaseClass;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3 import dmd.Type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
4 import dmd.PROT;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
5 import dmd.ClassDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
6 import dmd.Array;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
7 import dmd.TY;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
8 import dmd.TypeFunction;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
9 import dmd.Dsymbol;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
10 import dmd.FuncDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
11 import dmd.ArrayTypes;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
12
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
13 import core.stdc.stdlib;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
14 import core.stdc.string;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
15
4
d706d958e4e8 Step 2 of restoring GC functionality.
korDen
parents: 2
diff changeset
16 import core.memory;
2
7427ded8caf7 Removed unreferenced modules
korDen
parents: 0
diff changeset
17
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
18 class BaseClass
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
19 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
20 Type type; // (before semantic processing)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
21 PROT protection; // protection for the base interface
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
22
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
23 ClassDeclaration base;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
24 int offset; // 'this' pointer offset
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
25 Array vtbl; // for interfaces: Array of FuncDeclaration's
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
26 // making up the vtbl[]
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
27
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
28 //int baseInterfaces_dim;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
29 BaseClass[] baseInterfaces; // if BaseClass is an interface, these
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
30 // are a copy of the InterfaceDeclaration::interfaces
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
31
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
32 this()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
33 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
34 vtbl = new Array();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
35 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
36
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
37 this(Type type, PROT protection)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
38 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
39 //printf("BaseClass(this = %p, '%s')\n", this, type->toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
40 this.type = type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
41 this.protection = protection;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
42
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
43 vtbl = new Array();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
44 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
45
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
46 /****************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
47 * Fill in vtbl[] for base class based on member functions of class cd.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
48 * Input:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
49 * vtbl if !=null, fill it in
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
50 * newinstance !=0 means all entries must be filled in by members
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
51 * of cd, not members of any base classes of cd.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
52 * Returns:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
53 * true if any entries were filled in by members of cd (not exclusively
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
54 * by base classes)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
55 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
56 bool fillVtbl(ClassDeclaration cd, Array vtbl, int newinstance)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
57 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
58 ClassDeclaration id = base;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
59 int j;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
60 bool result = false;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
61
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
62 //printf("BaseClass.fillVtbl(this='%s', cd='%s')\n", base.toChars(), cd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
63 if (vtbl)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
64 vtbl.setDim(base.vtbl.dim);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
65
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
66 // first entry is ClassInfo reference
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
67 for (j = base.vtblOffset(); j < base.vtbl.dim; j++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
68 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
69 FuncDeclaration ifd = (cast(Dsymbol)base.vtbl.data[j]).isFuncDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
70 FuncDeclaration fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
71 TypeFunction tf;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
72
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
73 //printf(" vtbl[%d] is '%s'\n", j, ifd ? ifd.toChars() : "null");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
74
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
75 assert(ifd);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
76 // Find corresponding function in this class
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
77 tf = (ifd.type.ty == Tfunction) ? cast(TypeFunction)(ifd.type) : null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
78 fd = cd.findFunc(ifd.ident, tf);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
79 if (fd && !fd.isAbstract())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
80 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
81 //printf(" found\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
82 // Check that calling conventions match
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
83 if (fd.linkage != ifd.linkage)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
84 fd.error("linkage doesn't match interface function");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
85
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
86 // Check that it is current
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
87 if (newinstance &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
88 fd.toParent() != cd &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
89 ifd.toParent() == base
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
90 )
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
91 cd.error("interface function %s.%s is not implemented",
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
92 id.toChars(), ifd.ident.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
93
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
94 if (fd.toParent() == cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
95 result = true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
96 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
97 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
98 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
99 //printf(" not found\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
100 // BUG: should mark this class as abstract?
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
101 if (!cd.isAbstract())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
102 cd.error("interface function %s.%s isn't implemented", id.toChars(), ifd.ident.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
103 fd = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
104 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
105 if (vtbl)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
106 vtbl.data[j] = cast(void*)fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
107 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
108
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
109 return result;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
110 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
111
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
112 void copyBaseInterfaces(BaseClasses vtblInterfaces)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
113 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
114 //printf("+copyBaseInterfaces(), %s\n", base.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
115 // if (baseInterfaces_dim)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
116 // return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
117
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
118 baseInterfaces.length = base.interfaces_dim;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
119
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
120 int size = BaseClass.classinfo.init.length;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
121
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
122 //printf("%s.copyBaseInterfaces()\n", base.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
123 for (int i = 0; i < baseInterfaces.length; i++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
124 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
125 BaseClass b2 = base.interfaces[i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
126 assert(b2.vtbl.dim == 0); // should not be filled yet
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
127
2
7427ded8caf7 Removed unreferenced modules
korDen
parents: 0
diff changeset
128 void* mem = GC.malloc(size);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
129 memcpy(mem, cast(void*)b2, size);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
130
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
131 BaseClass b = cast(BaseClass)mem;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
132 baseInterfaces[i] = b;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
133
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
134 if (i) // single inheritance is i==0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
135 vtblInterfaces.push(cast(void*)b); // only need for M.I.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
136 b.copyBaseInterfaces(vtblInterfaces);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
137 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
138 //printf("-copyBaseInterfaces\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
139 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
140 }