tb0268.pp 2.8 KB

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