PageRenderTime 24ms CodeModel.GetById 11ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/runtime/dstatic.d

http://github.com/wilkie/djehuty
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