Runtime.Mod 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. (* Generic runtime support *)
  2. (* Copyright (C) Florian Negele *)
  3. MODULE Runtime;
  4. IMPORT SYSTEM, BaseTypes, Trace;
  5. TYPE TrapHandler* = PROCEDURE (number: SIZE);
  6. VAR trapHandler*: TrapHandler;
  7. (* compare strings,
  8. returns 0 if strings are equal,
  9. returns +1 if left is lexicographic greater than right,
  10. returns -1 if left is lexicographics smaller than right
  11. traps if src or destination is not 0X terminated and comparison is not finished
  12. *)
  13. PROCEDURE CompareString*(CONST left,right: ARRAY OF CHAR): SHORTINT;
  14. VAR i: LONGINT; res: SHORTINT; l,r: CHAR;
  15. BEGIN {UNCOOPERATIVE, UNCHECKED}
  16. i := 0; res := 0;
  17. LOOP
  18. l := left[i]; (* index check included *)
  19. r := right[i]; (* index check included *)
  20. IF (res = 0) THEN
  21. IF (l > r) THEN
  22. res := 1; EXIT
  23. ELSIF (l<r) THEN
  24. res := -1; EXIT
  25. ELSIF l=0X THEN
  26. EXIT
  27. END;
  28. END;
  29. INC(i);
  30. END;
  31. RETURN res
  32. END CompareString;
  33. (* copy string from src to dest, emits trap if not 0X terminated or destination too short *)
  34. PROCEDURE CopyString*(VAR dest: ARRAY OF CHAR; CONST src: ARRAY OF CHAR);
  35. VAR i: LONGINT; ch :CHAR; l1,l2: LONGINT;
  36. BEGIN {UNCOOPERATIVE, UNCHECKED}
  37. (*
  38. i := 0;
  39. REPEAT
  40. ch := src[i]; (* index check included *)
  41. dest[i] := ch; (* index check included *)
  42. INC(i);
  43. UNTIL ch=0X;
  44. *)
  45. (*! currently implemented: old PACO semantics *)
  46. l1 := LEN(dest);
  47. l2 := LEN(src);
  48. IF l2 < l1 THEN l1 := l2 END;
  49. SYSTEM.MOVE(ADDRESSOF(src[0]),ADDRESSOF(dest[0]),l1);
  50. dest[l1-1] := 0X; (* this implies that COPY assumes a string *)
  51. END CopyString;
  52. PROCEDURE EnsureAllocatedStack*(size: SIZE);
  53. VAR i: ADDRESS; temp: ADDRESS;
  54. BEGIN {UNCOOPERATIVE, UNCHECKED}
  55. FOR i := 0 TO size BY 4096 DO
  56. SYSTEM.GET(ADDRESSOF(i)-i,temp);
  57. (*
  58. SYSTEM.PUT(ADDRESSOF(val)-i,0);
  59. *)
  60. END;
  61. (*
  62. CODE{SYSTEM.i386}
  63. MOV EAX, [EBP+size]
  64. SHR EAX,12 ; divide by 4096
  65. MOV ECX,-4
  66. start:
  67. MOV EDX,[EBP+ECX]
  68. SUB ECX,4096
  69. TST EAX
  70. DEC EAX
  71. JNZ start
  72. *)
  73. END EnsureAllocatedStack;
  74. (** This procedure aborts the program and prints the number of the trap that caused the program to fail. *)
  75. (** The compiler calls this procedure for HALT statements or for unsatisfied ASSERT statements. *)
  76. PROCEDURE {NORETURN} Trap- (number: SIZE);
  77. PROCEDURE Abort EXTERN "Environment.Abort";
  78. BEGIN {UNCOOPERATIVE, UNCHECKED}
  79. IF trapHandler # NIL THEN
  80. trapHandler (number);
  81. ELSE
  82. Trace.Red; Trace.String ("trap: "); Trace.Int (number, 0); Trace.Ln;
  83. Trace.Default; Trace.StackFrames (1, 8, 20 * SIZE OF ADDRESS);
  84. END;
  85. Abort;
  86. END Trap;
  87. (** This procedure acquires memory and returns the address to the first byte or NIL if the allocation fails. *)
  88. (** The compiler implements all NEW statements with a call to this procedure. *)
  89. PROCEDURE New- (size: SIZE): ADDRESS;
  90. VAR result: ADDRESS; tries: SIZE;
  91. PROCEDURE CollectGarbage EXTERN "GarbageCollector.Collect";
  92. PROCEDURE Allocate EXTERN "Environment.Allocate" (size: SIZE): ADDRESS;
  93. BEGIN {UNCOOPERATIVE, UNCHECKED}
  94. FOR tries := 1 TO 10 DO
  95. result := Allocate (size);
  96. IF result # NIL THEN RETURN result END;
  97. CollectGarbage;
  98. END;
  99. RETURN NIL;
  100. END New;
  101. (** This procedure releases memory that was previously acquired by a call to the [[Runtime.New]] procedure. *)
  102. (** The compiler implements DISPOSE statements on types marked as disposable with a call to this procedure. *)
  103. PROCEDURE Dispose- (VAR pointer {UNTRACED}: BaseTypes.Pointer);
  104. PROCEDURE Deallocate EXTERN "Environment.Deallocate" (address: ADDRESS);
  105. PROCEDURE Watch EXTERN "GarbageCollector.Watch" (pointer {UNTRACED}: BaseTypes.Pointer);
  106. BEGIN {UNCOOPERATIVE, UNCHECKED}
  107. ASSERT (pointer # NIL);
  108. IF pointer IS BaseTypes.Object THEN pointer(BaseTypes.Object).Finalize END;
  109. IF (pointer IS BaseTypes.Pointer) & (pointer(BaseTypes.Pointer).nextWatched = NIL) THEN Watch (pointer(BaseTypes.Pointer));
  110. ELSE Deallocate (pointer) END; pointer := NIL;
  111. END Dispose;
  112. END Runtime.
  113. Runtime.Obw