TType.hx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import format.hl.Data;
  2. using format.hl.Tools;
  3. class TType {
  4. public var tid : Int;
  5. public var t : HLType;
  6. public var closure : HLType;
  7. public var bmp : hl.Bytes;
  8. public var hasPtr : Bool;
  9. public var isDyn : Bool;
  10. public var memFields : Array<TType>;
  11. public var memFieldsNames : Array<String>;
  12. public var constructs : Array<Array<TType>>;
  13. public var nullWrap : TType;
  14. public var ptrTags : haxe.io.Bytes;
  15. public var parentClass : TType;
  16. public var falsePositive = 0;
  17. public var falsePositiveIndexes = [];
  18. public function new(tid, t, ?cl) {
  19. this.tid = tid;
  20. this.t = t;
  21. this.closure = cl;
  22. isDyn = t.isDynamic();
  23. switch( t ) {
  24. case HFun(_):
  25. hasPtr = cl != null && cl.isPtr();
  26. default:
  27. hasPtr = t.containsPointer();
  28. }
  29. }
  30. public function match( t : TType ) {
  31. if( t == this ) return true;
  32. if( parentClass != null ) return parentClass.match(t);
  33. return false;
  34. }
  35. function tagPtr( pos : Int ) {
  36. var p = pos >> 5;
  37. if( ptrTags == null || ptrTags.length <= p ) {
  38. var nc = haxe.io.Bytes.alloc(p + 1);
  39. if( ptrTags != null ) nc.blit(0, ptrTags, 0, ptrTags.length);
  40. ptrTags = nc;
  41. }
  42. ptrTags.set(p, ptrTags.get(p) | (1 << (pos & 31)));
  43. }
  44. public function buildTypes( m : Memory, tvoid : TType ) {
  45. if( !hasPtr ) return;
  46. // layout of data inside memory
  47. inline function fill(fields:Array<TType>, pos:Int) {
  48. if( m.is64 ) {
  49. for( i in 0...pos >> m.ptrBits )
  50. if( fields[i] == null )
  51. fields[i] = tvoid;
  52. } else {
  53. // fill two slots for 64bit data
  54. var i = pos >> m.ptrBits;
  55. while( --i >= 0 )
  56. if( fields[i] == null )
  57. fields[i] = (fields[i-1] == null || fields[i-1].t != HF64) ? tvoid : fields[i-1];
  58. }
  59. }
  60. switch( t ) {
  61. case HObj(p):
  62. var protos = [p];
  63. while( p.tsuper != null )
  64. switch( p.tsuper ) {
  65. case HObj(p2):
  66. protos.unshift(p2);
  67. p = p2;
  68. default:
  69. }
  70. memFields = [];
  71. memFieldsNames = [];
  72. var fcount = 0;
  73. for( p in protos )
  74. fcount += p.fields.length;
  75. var pos = 1 << m.ptrBits; // type
  76. for( p in protos )
  77. for( f in p.fields ) {
  78. var size = m.typeSize(f.t);
  79. pos = align(pos, size);
  80. memFields[pos >> m.ptrBits] = m.getType(f.t);
  81. memFieldsNames[pos >> m.ptrBits] = f.name;
  82. if( f.t.isPtr() ) tagPtr(pos >> m.ptrBits);
  83. pos += size;
  84. }
  85. fill(memFields, pos);
  86. case HEnum(e):
  87. constructs = [];
  88. for( c in e.constructs ) {
  89. var pos = 4; // index
  90. var fields = [];
  91. for( t in c.params ) {
  92. var size = m.typeSize(t);
  93. pos = align(pos, size);
  94. fields[pos>>m.ptrBits] = m.getType(t);
  95. if( t.isPtr() ) tagPtr(pos >> m.ptrBits);
  96. pos += size;
  97. }
  98. fill(fields, pos);
  99. constructs.push(fields);
  100. }
  101. case HVirtual(fl):
  102. memFields = [
  103. tvoid, // type
  104. m.getType(HDyn), // obj
  105. m.getType(HDyn), // next
  106. ];
  107. memFieldsNames = [];
  108. var pos = (fl.length + 3) << m.ptrBits;
  109. tagPtr(1);
  110. tagPtr(2);
  111. for( f in fl ) {
  112. var size = m.typeSize(f.t);
  113. pos = align(pos, size);
  114. memFields[pos >> m.ptrBits] = m.getType(f.t);
  115. memFieldsNames[pos >> m.ptrBits] = f.name;
  116. if( f.t.isPtr() ) tagPtr(pos >> m.ptrBits);
  117. pos += size;
  118. }
  119. fill(memFields, pos);
  120. // keep null our fields pointers since they might point to a DynObj data head
  121. for( i in 0...fl.length )
  122. memFields[i+3] = null;
  123. case HNull(t):
  124. if( m.is64 )
  125. memFields = [tvoid, m.getType(t)];
  126. else
  127. memFields = [tvoid, tvoid, m.getType(t), tvoid];
  128. case HFun(_):
  129. memFields = [tvoid, tvoid, tvoid, m.getType(closure)];
  130. default:
  131. }
  132. }
  133. inline function align(pos, size) {
  134. var d = pos & (size - 1);
  135. if( d != 0 ) pos += size - d;
  136. return pos;
  137. }
  138. public function toString() {
  139. switch( t ) {
  140. case HAbstract(p):
  141. return p;
  142. default:
  143. return t.toString();
  144. }
  145. }
  146. }