home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 116.lha / SmallTalk / Sources / MEMORY.H < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-20  |  5.6 KB  |  172 lines

  1. /*
  2.     Little Smalltalk, version 2
  3.     Written by Tim Budd, Oregon State University, July 1987
  4. */
  5.  
  6. # define streq(a,b) (strcmp(a,b) == 0)
  7.  
  8. /*
  9.     The first major decision to be made in the memory manager is what
  10. an entity of type object really is.  Two obvious choices are a pointer (to 
  11. the actual object memory) or an index into an object table.  We decided to
  12. use the latter, although either would work.
  13.     Similarly, one can either define the token object using a typedef,
  14. or using a define statement.  Either one will work (check this?)
  15. */
  16.  
  17. typedef short object;
  18.  
  19. /*
  20.     The memory module itself is defined by over a dozen routines.
  21. All of these could be defined by procedures, and indeed this was originally
  22. done.  However, for efficiency reasons, many of these procedures can be
  23. replaced by macros generating in-line code.  For the latter approach
  24. to work, the structure of the object table must be known.  For this reason,
  25. it is given here.  Note, however, that ONLY the macros described in this
  26. file make use of this structure: therefore modifications or even complete
  27. replacement is possible as long as the interface remains consistent
  28.  
  29. */
  30.  
  31. struct objectStruct {
  32.     object class;
  33.     short referenceCount;
  34.     byte size;
  35.     byte type;
  36.     object *memory;
  37.     };
  38.  
  39. extern struct objectStruct objectTable[];
  40.  
  41. /* types of object memory */
  42. # define objectMemory 0
  43. # define byteMemory 1
  44. # define charMemory 2
  45. # define floatMemory 3
  46.  
  47. # define isString(x) ((objectTable[x>>1].type == charMemory) || (objectTable[x>>1].type == byteMemory))
  48. # define isFloat(x)  (objectTable[x>>1].type == floatMemory)
  49.  
  50. /*
  51.     The most basic routines to the memory manager are incr and decr,
  52. which increment and decrement reference counts in objects.  By separating
  53. decrement from memory freeing, we could replace these as procedure calls
  54. by using the following macros:
  55. extern object incrobj;
  56. # define incr(x) if ((incrobj=(x))&&!isInteger(incrobj)) \
  57. objectTable[incrobj>>1].referenceCount++
  58. #  define decr(x) if (((incrobj=x)&&!isInteger(incrobj))&&\
  59. (--objectTable[incrobj>>1].referenceCount<=0)) sysDecr(incrobj);*/
  60. /*
  61. notice that the argument x is first assigned to a global variable; this is
  62. in case evaluation of x results in side effects (such as assignment) which
  63. should not be repeated. */
  64.  
  65. extern noreturn sysDecr(OBJ);
  66.  
  67. # ifndef incr
  68. extern void incr(OBJ);
  69. # endif
  70. # ifndef decr
  71. extern void decr(OBJ);
  72. # endif
  73.  
  74. /*
  75.     The next most basic routines in the memory module are those that
  76. allocate blocks of storage.  There are three routines:
  77.     allocObject(size) - allocate an array of objects
  78.     allocByte(size) - allocate an array of bytes
  79.     allocChar(size) - allocate an array of character values
  80.     allocSymbol(value) - allocate a string value
  81.     allocInt(value) - allocate an integer value
  82.     allocFloat(value) - allocate a floating point object
  83. again, these may be macros, or they may be actual procedure calls
  84. */
  85.  
  86. extern object alcObject(INT X INT);    /* the actual routine */
  87. # define allocObject(size) alcObject(size, objectMemory)
  88. # define allocByte(size) alcObject(((size)+1)/2, byteMemory)
  89. # define allocChar(size) alcObject(((size)+1)/2, charMemory)
  90. extern object allocSymbol(STR);
  91. # define allocInt(value) ((value<0)?value:(value<<1)+1)
  92. extern object allocFloat(FLOAT);
  93.  
  94. /*
  95.     integer objects are (but need not be) treated specially.
  96. In this memory manager, negative integers are just left as is, but
  97. positive integers are changed to x*2+1.  Either a negative or an odd
  98. number is therefore an integer, while a nonzero even number is an
  99. object pointer (multiplied by two).  Zero is reserved for the object ``nil''
  100. Since newInteger does not fill in the class field, it can be given here.
  101. If it was required to use the class field, it would have to be deferred
  102. until names.h
  103. */
  104.  
  105. extern object intobj;
  106. # define isInteger(x) ((x) & 0x8001)
  107. # define newInteger(x) ( (intobj = x)<0 ? intobj : (intobj<<1)+1 )
  108. # define intValue(x) ( (intobj = x)<0 ? intobj : (intobj>>1) )
  109.  
  110. /*
  111.     in addition to alloc floating point routine given above,
  112. another routine must be provided to go the other way.  Note that
  113. the routine newFloat, which fills in the class field as well, must
  114. wait until the global name table is known, in names.h
  115. */
  116. extern double floatValue(OBJ);
  117.  
  118. /*
  119.     there are four routines used to access fields within an object.
  120. Again, some of these could be replaced by macros, for efficiency
  121.     basicAt(x, i) - ith field (start at 1) of object x
  122.     basicAtPut(x, i, v) - put value v in object x
  123.     byteAt(x, i) - ith field (start at 0) of object x
  124.     byteAtPut(x, i, v) - put value v in object x
  125.  
  126. # define basicAt(x,i) (sysMemPtr(x)[i-1])
  127. */
  128. # define byteAt(x, i) (charPtr(x)[i-1])
  129.  
  130. # ifndef basicAt
  131. extern object basicAt(OBJ X INT);
  132. # endif
  133. # ifndef basicAtPut
  134. extern void basicAtPut(OBJ X INT X OBJ);
  135. # endif
  136. # ifndef byteAt
  137. extern int byteAt(OBJ X INT);
  138. # endif
  139. # ifndef byteAtPut
  140. extern void byteAtPut(OBJ X INT X INT);
  141. # endif
  142.  
  143. /*
  144.     Finally, a few routines (or macros) are used to access or set
  145. class fields and size fields of objects
  146. */
  147.  
  148. # define classField(x) objectTable[x>>1].class
  149. # define setClass(x,y) incr(classField(x)=y)
  150.  
  151. # define objectSize(x) byteToInt(objectTable[x>>1].size)
  152.  
  153. # define sysMemPtr(x) objectTable[x>>1].memory
  154. extern object sysobj;
  155. # define memoryPtr(x) (isInteger(sysobj = x)?(object *) 0:sysMemPtr(sysobj))
  156. # define bytePtr(x) ((byte *) memoryPtr(x))
  157. # define charPtr(x) ((char *) memoryPtr(x))
  158.  
  159. # define nilobj (object) 0
  160.  
  161. /*
  162.     these two objects are the source of all objects in the system
  163. */
  164. extern object symbols;
  165. extern object globalNames;
  166.  
  167. extern noreturn sysError (STR X STR);
  168. extern boolean debugging;
  169. extern noreturn initMemoryManager(NOARGS);
  170. extern noreturn imageRead(FILEP);
  171. extern noreturn imageWrite(FILEP);
  172.