tbs0312.pp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. { Program that showss a problem if
  2. Self is not reloaded in %esi register
  3. at entry in local procedure inside method }
  4. uses
  5. objects;
  6. type
  7. {$ifndef FPC}
  8. sw_integer = integer;
  9. {$endif not FPC}
  10. PMYObj = ^TMyObj;
  11. TMyObj = Object(TObject)
  12. x : longint;
  13. Constructor Init(ax : longint);
  14. procedure display;virtual;
  15. end;
  16. PMYObj2 = ^TMyObj2;
  17. TMyObj2 = Object(TMyObj)
  18. y : longint;
  19. Constructor Init(ax,ay : longint);
  20. procedure display;virtual;
  21. end;
  22. PMyCollection = ^TMyCollection;
  23. TMyCollection = Object(TCollection)
  24. function At(I : sw_integer) : PMyObj;
  25. procedure DummyThatShouldNotBeCalled;virtual;
  26. end;
  27. { TMy is also a TCollection so that
  28. ShowMy and DummyThatShouldNotBeCalled are at same position in VMT }
  29. TMy = Object(TCollection)
  30. Col : PMyCollection;
  31. MyObj : PMyObj;
  32. ShowMyCalled : boolean;
  33. constructor Init;
  34. destructor Done;virtual;
  35. procedure ShowAll;
  36. procedure AddMyObj(x : longint);
  37. procedure AddMyObj2(x,y : longint);
  38. procedure ShowMy;virtual;
  39. end;
  40. Constructor TMyObj.Init(ax : longint);
  41. begin
  42. Inherited Init;
  43. x:=ax;
  44. end;
  45. Procedure TMyObj.Display;
  46. begin
  47. Writeln('x = ',x);
  48. end;
  49. Constructor TMyObj2.Init(ax,ay : longint);
  50. begin
  51. Inherited Init(ax);
  52. y:=ay;
  53. end;
  54. Procedure TMyObj2.Display;
  55. begin
  56. Writeln('x = ',x,' y = ',y);
  57. end;
  58. Function TMyCollection.At(I : sw_integer) : PMyObj;
  59. begin
  60. At:=Inherited At(I);
  61. end;
  62. Procedure TMyCollection.DummyThatShouldNotBeCalled;
  63. begin
  64. Writeln('This method should never be called');
  65. Abstract;
  66. end;
  67. Constructor TMy.Init;
  68. begin
  69. New(Col,Init(5,5));
  70. MyObj:=nil;
  71. ShowMyCalled:=false;
  72. end;
  73. Destructor TMy.Done;
  74. begin
  75. Dispose(Col,Done);
  76. Inherited Done;
  77. end;
  78. Procedure TMy.ShowAll;
  79. procedure ShowIt(P : pointer);{$ifdef TP}far;{$endif}
  80. begin
  81. ShowMy;
  82. PMyObj(P)^.Display;
  83. end;
  84. begin
  85. Col^.ForEach(@ShowIt);
  86. end;
  87. Procedure TMy.ShowMy;
  88. begin
  89. if assigned(MyObj) then
  90. MyObj^.Display;
  91. ShowMyCalled:=true;
  92. end;
  93. Procedure TMy.AddMyObj(x : longint);
  94. begin
  95. MyObj:=New(PMyObj,Init(x));
  96. Col^.Insert(MyObj);
  97. end;
  98. Procedure TMy.AddMyObj2(x,y : longint);
  99. begin
  100. MyObj:=New(PMyObj2,Init(x,y));
  101. Col^.Insert(MyObj);
  102. end;
  103. var
  104. My : TMy;
  105. begin
  106. My.Init;
  107. My.AddMyObj(5);
  108. My.AddMyObj2(4,3);
  109. My.AddMyObj(43);
  110. { MyObj field is now a PMyObj with value 43 }
  111. My.ShowAll;
  112. If not My.ShowMyCalled then
  113. begin
  114. Writeln('ShowAll does not work correctly');
  115. Halt(1);
  116. end;
  117. My.Done;
  118. end.