Block.hx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. abstract Pointer(haxe.Int64) {
  2. public var value(get,never) : haxe.Int64;
  3. inline function get_value() return this;
  4. inline function new(v) this = v;
  5. public inline function isNull() {
  6. return this == 0;
  7. }
  8. public inline function offset( i : Int ) : Pointer {
  9. return cast (this + i);
  10. }
  11. public inline function sub( p : Pointer ) : Int {
  12. return haxe.Int64.toInt(this - p.value);
  13. }
  14. public inline function toString() {
  15. return "0x"+(this.high == 0 ? StringTools.hex(this.high, 8) : "")+StringTools.hex(this.low,8);
  16. }
  17. public inline function shift( k : Int ) : haxe.Int64 {
  18. return haxe.Int64.shr(this,k);
  19. }
  20. public static var NULL(get,never) : Pointer;
  21. inline static function get_NULL() return new Pointer(0);
  22. }
  23. @:enum abstract PageKind(Int) {
  24. var PDynamic = 0;
  25. var PRaw = 1;
  26. var PNoPtr = 2;
  27. var PFinalizer = 3;
  28. }
  29. class Page {
  30. public var addr : Pointer;
  31. public var kind : PageKind;
  32. public var size : Int;
  33. public var reserved : Int;
  34. public var dataPosition : Int = -1;
  35. public function new() {
  36. }
  37. public inline function memHasPtr() {
  38. return kind == PDynamic || kind == PRaw;
  39. }
  40. }
  41. class Stack {
  42. public var base : Pointer;
  43. public var contents : Array<Pointer>;
  44. public function new() {
  45. }
  46. }
  47. enum BlockTypeKind {
  48. KHeader;
  49. KRoot;
  50. KAbstractData;
  51. KDynObjData;
  52. KInferred( t : TType, k : BlockTypeKind );
  53. }
  54. class BlockSub {
  55. public var b : Block;
  56. public var fid : Int;
  57. public function new(b,fid) {
  58. this.b = b;
  59. this.fid = fid;
  60. }
  61. }
  62. class Block {
  63. public static var MARK_UID = 0;
  64. public var page : Page;
  65. public var addr : Pointer;
  66. public var size : Int;
  67. public var typePtr : Pointer;
  68. public var owner : Block;
  69. public var type(default, set) : TType;
  70. public var typeKind : BlockTypeKind;
  71. public var depth : Int = -1;
  72. public var mark : Int = -1;
  73. public var subs : Array<BlockSub>; // can be null
  74. public var parents : Array<Block>; // if multiple owners
  75. public function new() {
  76. }
  77. function set_type( t : TType ) {
  78. if( t != null && t.t == HF64 && page.kind != PNoPtr )
  79. throw "!";
  80. return type = t;
  81. }
  82. public function addParent(b:Block,fid:Int=0) {
  83. if( owner == null ) {
  84. owner = b;
  85. } else {
  86. if( parents == null ) parents = [owner];
  87. parents.push(b);
  88. }
  89. if( b.subs == null ) b.subs = [];
  90. b.subs.push(new BlockSub(this,fid));
  91. }
  92. public function makeTID( prev : Block, withField : Bool ) {
  93. if( type == null )
  94. return 0;
  95. if( withField )
  96. for( s in subs )
  97. if( s.b == prev )
  98. return type.tid | (s.fid << 24);
  99. return type.tid;
  100. }
  101. public function getParents() {
  102. return parents != null ? parents : owner == null ? [] : [owner];
  103. }
  104. public function markDepth() {
  105. var d = depth + 1;
  106. var all = subs;
  107. if( all == null ) return;
  108. while( all.length > 0 ) {
  109. var out = [];
  110. for( b in all ) {
  111. var b = b.b;
  112. if( b.depth < 0 || b.depth > d ) {
  113. b.depth = d;
  114. if( b.subs != null ) for( s in b.subs ) out.push(s);
  115. }
  116. }
  117. all = out;
  118. d++;
  119. }
  120. }
  121. public function finalize() {
  122. if( parents == null ) return;
  123. inline function getPriority(b:Block) {
  124. var d = -b.depth * 5;
  125. if( b.type == null ) return d-2;
  126. if( !b.type.hasPtr ) return d-1; // false positive
  127. return switch( b.type.t ) {
  128. case HFun(_): d;
  129. case HVirtual(_): d+1;
  130. default: d+2;
  131. }
  132. }
  133. parents.sort(function(p1, p2) return getPriority(p2) - getPriority(p1));
  134. owner = parents[0];
  135. }
  136. function removeParent( p : Block ) {
  137. if( parents != null ) {
  138. parents.remove(p);
  139. if( parents.length == 0 ) parents = null;
  140. }
  141. if( owner == p )
  142. owner = parents == null ? null : parents[0];
  143. }
  144. public function removeChildren() {
  145. if( subs != null ) {
  146. for( s in subs )
  147. s.b.removeParent(this);
  148. subs = null;
  149. }
  150. }
  151. }
  152. @:generic
  153. class PointerMap<T> {
  154. var lookup : Map<Int,Map<Int,T>>;
  155. public function new() {
  156. lookup = new Map();
  157. }
  158. public function set( p : Pointer, v : T ) {
  159. var c = lookup.get(p.value.high);
  160. if( c == null ) {
  161. c = new Map();
  162. lookup.set(p.value.high, c);
  163. }
  164. c.set(p.value.low, v);
  165. }
  166. public function get( p : Pointer ) : T {
  167. if( p.isNull() ) return null;
  168. var c = lookup.get(p.value.high);
  169. if( c == null ) return null;
  170. return c.get(p.value.low);
  171. }
  172. }