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