/runtime/dstatic.d
D | 163 lines | 102 code | 30 blank | 31 comment | 22 complexity | 0953c72a6bba44a28ddb6838800a5363 MD5 | raw file
1/* 2 * dstatic.d 3 * 4 * This module implements the static subset of D. 5 * 6 */ 7 8module runtime.dstatic; 9 10import runtime.util; 11import runtime.common; 12 13extern(C): 14 15/****************************************** 16 * Given a pointer: 17 * If it is an Object, return that Object. 18 * If it is an interface, return the Object implementing the interface. 19 * If it is null, return null. 20 * Else, undefined crash 21 */ 22 23Object _d_toObject(void* p) { 24 Object o; 25 26 if (p) { 27 o = cast(Object)p; 28 ClassInfo oc = o.classinfo; 29 Interface *pi = **cast(Interface ***)p; 30 31 /* Interface.offset lines up with ClassInfo.name.ptr, 32 * so we rely on pointers never being less than 64K, 33 * and Objects never being greater. 34 */ 35 if (pi.offset < 0x10000) { 36 //printf("\tpi.offset = %d\n", pi.offset); 37 o = cast(Object)(p - pi.offset); 38 } 39 } 40 return o; 41} 42 43/************************************* 44 * Attempts to cast Object o to class c. 45 * Returns o if successful, null if not. 46 */ 47 48Object _d_interface_cast(void* p, ClassInfo c) { 49 Object o; 50 51 //printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name); 52 if (p) { 53 Interface *pi = **cast(Interface ***)p; 54 55 //printf("\tpi.offset = %d\n", pi.offset); 56 o = cast(Object)(p - pi.offset); 57 return _d_dynamic_cast(o, c); 58 } 59 return o; 60} 61 62Object _d_dynamic_cast(Object o, ClassInfo c) { 63 ClassInfo oc; 64 size_t offset = 0; 65 66 //printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name); 67 68 if (o) { 69 oc = o.classinfo; 70 if (_d_isbaseof2(oc, c, offset)) { 71 //printf("\toffset = %d\n", offset); 72 o = cast(Object)(cast(void*)o + offset); 73 } 74 else 75 o = null; 76 } 77 //printf("\tresult = %p\n", o); 78 return o; 79} 80 81int _d_isbaseof2(ClassInfo oc, ClassInfo c, inout size_t offset) { 82 int i; 83 84 if (oc is c) 85 return 1; 86 do { 87 if (oc.base is c) 88 return 1; 89 for (i = 0; i < oc.interfaces.length; i++) { 90 ClassInfo ic; 91 92 ic = oc.interfaces[i].classinfo; 93 if (ic is c) { 94 offset = oc.interfaces[i].offset; 95 return 1; 96 } 97 } 98 for (i = 0; i < oc.interfaces.length; i++) { 99 ClassInfo ic; 100 101 ic = oc.interfaces[i].classinfo; 102 if (_d_isbaseof2(ic, c, offset)) { 103 offset = oc.interfaces[i].offset; 104 return 1; 105 } 106 } 107 oc = oc.base; 108 } while (oc); 109 return 0; 110} 111 112int _d_isbaseof(ClassInfo oc, ClassInfo c) { 113 int i; 114 115 if (oc is c) 116 return 1; 117 do { 118 if (oc.base is c) 119 return 1; 120 for (i = 0; i < oc.interfaces.length; i++) { 121 ClassInfo ic; 122 123 ic = oc.interfaces[i].classinfo; 124 if (ic is c || _d_isbaseof(ic, c)) 125 return 1; 126 } 127 oc = oc.base; 128 } while (oc); 129 return 0; 130} 131 132/********************************* 133 * Find the vtbl[] associated with Interface ic. 134 */ 135 136void *_d_interface_vtbl(ClassInfo ic, Object o) { 137 int i; 138 ClassInfo oc; 139 140 //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic); 141 142 assert(o); 143 144 oc = o.classinfo; 145 for (i = 0; i < oc.interfaces.length; i++) { 146 ClassInfo oic; 147 148 oic = oc.interfaces[i].classinfo; 149 if (oic is ic) { 150 return cast(void *)oc.interfaces[i].vtbl; 151 } 152 } 153 assert(0); 154} 155 156int _d_obj_eq(Object o1, Object o2) { 157 return o1 is o2 || (o1 && o1.opEquals(o2)); 158} 159 160int _d_obj_cmp(Object o1, Object o2) { 161 return o1.opCmp(o2); 162} 163