[Oberon] Static variable overflow (bug?)

Andreas Pirklbauer andreas_pirklbauer at yahoo.com
Wed Feb 26 14:21:31 CET 2020


A simple fix to make the program “MyViewer” below work, i.e. to allow variable offsets < 64KB 
is to fix a bug in the current ORG.Put1a, by changing it


From:

  PROCEDURE Put1a(op, a, b, im: LONGINT);
  BEGIN (*same as Put1, but with range test  -10000H <= im < 10000H*)
    IF (im >= -10000H) & (im <= 0FFFFH) THEN Put1(op, a, b, im)
    ELSE Put1(Mov+U, RH, 0, im DIV 10000H);
      IF im MOD 10000H # 0 THEN Put1(Ior, RH, RH, im MOD 10000H) END ;
      Put0(op, a, b, RH)
    END
  END Put1a;

To:

 PROCEDURE Put1a(op, a, b, im: LONGINT);
  BEGIN (*same as Put1, but with range test  -10000H <= im < 10000H*)
    IF (im >= -10000H) & (im <= 0FFFFH) THEN Put1(op, a, b, im)
    ELSE Put1(Mov+U, RH+1, 0, im DIV 10000H);
      IF im MOD 10000H # 0 THEN Put1(Ior, RH+1, RH+1, im MOD 10000H) END ;
      Put0(op, a, b, RH+1)
    END
  END Put1a;

i.e. by replacing RH with RH+1 in the ELSE clause.

Note that this is a quick fix which neither checks whether there are in fact enough registers available (as incR does) nor does any register optimization. But it will make the program below work..

-ap

---------------------

MODULE MyViewer;  
(* Test of the menu line of a viewer *)

IMPORT Display, Viewers, Oberon, MenuViewers, TextFrames;

CONST 
   max = 16377;   (* If max >= 16367 the frame name disappears; If max >= 16377 the whole menu line disappears! *)
   menu = "System.Close System.Copy System.Grow"; 

TYPE 
   XYframe = POINTER TO XYframeDesc;
   XYframeDesc = RECORD (Display.FrameDesc) END;

VAR bitmap: ARRAY max OF SET;  (* with this variable present the menu may remain empty! *)


PROCEDURE Restore(F: XYframe);
BEGIN 
   Oberon.RemoveMarks(F.X, F.Y, F.W, F.H);
   Display.ReplConst(Display.black, F.X, F.Y, F.W, F.H, Display.replace);  (* clear *)
END Restore;


PROCEDURE Handle(F: Display.Frame; VAR M: Display.FrameMsg);
   VAR F1: XYframe;
BEGIN  
   CASE F OF XYframe:
      CASE M OF 
         Oberon.InputMsg:
            IF M.id = Oberon.track THEN Oberon.DrawMouseArrow(M.X, M.Y) END |
         Oberon.CopyMsg:
               Oberon.RemoveMarks(F.X, F.Y, F.W, F.H); NEW(F1); F1^ := F^; M.F := F1 |
         MenuViewers.ModifyMsg:
            IF (M.Y # F.Y) OR (M.H # F.H) THEN F.Y := M.Y; F.H := M.H; Restore(F) END        
      END
   END
END Handle;


PROCEDURE Open*;
   VAR F: XYframe;    V: Viewers.Viewer;   x, y: INTEGER;
BEGIN
   NEW(F);   F.handle := Handle; 
   Oberon.AllocateUserViewer(Oberon.Par.vwr.X, x, y); 
   V := MenuViewers.New(TextFrames.NewMenu("MyViewer", menu), F, TextFrames.menuH, x, y)
END Open;

END MyViewer.


More information about the Oberon mailing list