home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / sharewar / dos / program / gs300sr1 / gs300sr1.exe / IPACKED.H < prev    next >
Text File  |  1994-07-27  |  5KB  |  109 lines

  1. /* Copyright (C) 1991, 1992, 1993, 1994 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* ipacked.h */
  20. /* Packed array format for Ghostscript */
  21.  
  22. /*
  23.  
  24. In a packed array, an element may either be a 2-byte ref_packed or a
  25. full-size ref (8 or 16 bytes).  We carefully arrange the first two bytes,
  26. which are either an entire ref_packed or the type_attrs member of a ref,
  27. so that we can distinguish the 2 forms.  The encoding:
  28.  
  29.     00tttttt exrwsfnm    full-size ref
  30.     010mjjjj jjjjjjjj    executable operator (so bind can work)
  31.     011mvvvv vvvvvvvv    integer (biased by packed_min_intval)
  32.     100m---- --------    (not used)
  33.     101m---- --------    (not used)
  34.     110miiii iiiiiiii    literal name
  35.     111miiii iiiiiiii    executable name
  36.  
  37. The m bit is the mark bit for the garbage collector.
  38.  
  39. The jjj index of executable operators is either the index of the operator
  40. in the op_def_table, if the index is less than op_def_count, or the index
  41. of the definition in the op_array_table (subtracting op_def_count first).
  42.  
  43. The iii index of names is the one that the name machinery already
  44. maintains.  A name whose index is larger than will fit in the packed
  45. representation must be represented as a full-size ref.
  46.  
  47. There are two packed array types, t_mixedarray and t_shortarray.  A
  48. t_mixedarray can have a mix of packed and full-size elements; a
  49. t_shortarray has all packed elements.  The 'size' of a packed array is the
  50. number of elements, not the number of bytes it occupies.
  51.  
  52. Packed array elements can be distinguished from full-size elements, so we
  53. allow the interpreter to simply execute all the different kinds of arrays
  54. directly.  However, if we really allowed free mixing of packed and
  55. full-size elements, this could lead to unaligned placement of full-size
  56. refs; some machines can't handle unaligned accesses of this kind.  To
  57. guarantee that full-size elements in mixed arrays are always properly
  58. aligned, if a full-size ref must be aligned at an address which is 0 mod
  59. N, we convert up to N/2-1 preceding packed elements into full-size
  60. elements, when creating the array, so that the alignment is preserved.
  61. The only code this actually affects is in make_packed_array and in the
  62. code for compacting refs in the garbage collector.
  63.  
  64. Note that code in zpacked.c and interp.c knows more about the
  65. representation of packed elements than the definitions in this file would
  66. imply.  Read the code carefully if you change the representation.
  67.  
  68.  */
  69.  
  70. #define packed_type_shift 13
  71. #define packed_value_bits 12
  72. typedef enum {
  73.     pt_full_ref = 0,
  74. #define pt_min_packed 2
  75.     pt_executable_operator = 2,
  76.     pt_integer = 3,
  77. #define pt_min_name 6
  78.     pt_literal_name = 6,
  79. #define pt_min_exec_name 7
  80.     pt_executable_name = 7
  81. } packed_type;
  82. #define packed_per_ref (sizeof(ref) / sizeof(ref_packed))
  83. #define align_packed_per_ref\
  84.   (arch_align_ref_mod / arch_align_short_mod)
  85. #define pt_tag(pt) ((ref_packed)(pt) << packed_type_shift)
  86. #define packed_value_mask ((1 << packed_value_bits) - 1)
  87. #define packed_max_value packed_value_mask
  88. #define r_is_packed(rp)  (*(const ref_packed *)(rp) >= pt_tag(pt_min_packed))
  89. /* Names */
  90. #define r_packed_is_name(prp) (*(prp) >= pt_tag(pt_min_name))
  91. #define r_packed_is_exec_name(prp) (*(prp) >= pt_tag(pt_min_exec_name))
  92. #define packed_name_max_index packed_max_value
  93. #define packed_name_index(prp) (*(prp) & packed_value_mask)
  94. /* Integers */
  95. #define packed_min_intval (-(1 << (packed_value_bits - 1)))
  96. #define packed_max_intval ((1 << (packed_value_bits - 1)) - 1)
  97. #define packed_int_mask packed_value_mask
  98.  
  99. /* Packed ref marking */
  100. #define lp_mark 0x1000
  101. #define r_has_pmark(rp) (*(rp) & lp_mark)
  102. #define r_set_pmark(rp) (*(rp) |= lp_mark)
  103. #define r_clear_pmark(rp) (*(rp) &= ~lp_mark)
  104. #define r_store_pmark(rp,pm) (*(rp) = (*(rp) & ~lp_mark) | (pm))
  105.  
  106. /* Advance to the next element in a packed array. */
  107. #define packed_next(prp)\
  108.   (r_is_packed(prp) ? prp + 1 : prp + packed_per_ref)
  109.