ivmspace.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* Copyright (C) 1992, 1993, 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
  2. This file is part of AFPL Ghostscript.
  3. AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  4. distributor accepts any responsibility for the consequences of using it, or
  5. for whether it serves any particular purpose or works at all, unless he or
  6. she says so in writing. Refer to the Aladdin Free Public License (the
  7. "License") for full details.
  8. Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. in a plain ASCII text file named PUBLIC. The License grants you the right
  10. to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. conditions described in the License. Among other things, the License
  12. requires that the copyright notice and this notice be preserved on all
  13. copies.
  14. */
  15. /*$Id: ivmspace.h,v 1.2 2000/09/19 19:00:47 lpd Exp $ */
  16. /* Local/global space management */
  17. /* Requires iref.h */
  18. #ifndef ivmspace_INCLUDED
  19. # define ivmspace_INCLUDED
  20. #include "gsgc.h"
  21. /*
  22. * r_space_bits and r_space_shift, which define the bits in a ref
  23. * that carry VM space information, are defined in iref.h.
  24. * r_space_bits must be at least 2.
  25. */
  26. #define a_space (((1 << r_space_bits) - 1) << r_space_shift)
  27. /*
  28. * The i_vm_xxx values are defined in gsgc.h.
  29. */
  30. typedef enum {
  31. avm_foreign = (i_vm_foreign << r_space_shift),
  32. avm_system = (i_vm_system << r_space_shift),
  33. avm_global = (i_vm_global << r_space_shift),
  34. avm_local = (i_vm_local << r_space_shift),
  35. avm_max = avm_local
  36. } avm_space;
  37. #define r_space(rp) (avm_space)(r_type_attrs(rp) & a_space)
  38. #define r_space_index(rp) ((int)r_space(rp) >> r_space_shift)
  39. #define r_set_space(rp,space) r_store_attrs(rp, a_space, (uint)space)
  40. /*
  41. * According to the PostScript language specification, attempting to store
  42. * a reference to a local object into a global object must produce an
  43. * invalidaccess error. However, systemdict must be able to refer to
  44. * a number of local dictionaries such as userdict and errordict.
  45. * Therefore, we implement a special hack in 'def' that allows such stores
  46. * if the dictionary being stored into is systemdict (which is normally
  47. * only writable during initialization) or a dictionary that appears
  48. * in systemdict (such as level2dict), and the current save level is zero
  49. * (to guarantee that we can't get dangling pointers).
  50. * We could allow this for any global dictionary, except that the garbage
  51. * collector must treat any such dictionaries as roots when collecting
  52. * local VM without collecting global VM.
  53. * We make a similar exception for .makeglobaloperator; this requires
  54. * treating the operator table as a GC root as well.
  55. *
  56. * We extend the local-into-global store check because we have four VM
  57. * spaces (local, global, system, and foreign), and we allow PostScript
  58. * programs to create objects in any of the first three. If we define
  59. * the "generation" of an object as foreign = 0, system = 1, global = 2,
  60. * and local = 3, then a store is legal iff the generation of the object
  61. * into which a pointer is being stored is greater than or equal to
  62. * the generation of the object into which the store is occurring.
  63. *
  64. * We must check for local-into-global stores in three categories of places:
  65. *
  66. * - The scanner, when it encounters a //name inside {}.
  67. *
  68. * - All operators that allocate ref-containing objects and also
  69. * store into them:
  70. * packedarray gstate makepattern?
  71. * makefont scalefont definefont filter
  72. *
  73. * - All operators that store refs into existing objects
  74. * ("operators" marked with * are actually PostScript procedures):
  75. * put(array) putinterval(array) astore copy(to array)
  76. * def store* put(dict) copy(dict)
  77. * dictstack execstack .make(global)operator
  78. * currentgstate defineusername
  79. */
  80. /* Test whether an object is in local space, */
  81. /* which implies that we need not check when storing into it. */
  82. #define r_is_local(rp) (r_space(rp) == avm_local)
  83. /* Test whether an object is foreign, i.e., outside known space. */
  84. #define r_is_foreign(rp) (r_space(rp) == avm_foreign)
  85. /* Check whether a store is allowed. */
  86. #define store_check_space(destspace,rpnew)\
  87. if ( r_space(rpnew) > (destspace) )\
  88. return_error(e_invalidaccess)
  89. #define store_check_dest(rpdest,rpnew)\
  90. store_check_space(r_space(rpdest), rpnew)
  91. /* BACKWARD COMPATIBILITY (not used by any Ghostscript code per se) */
  92. #define check_store_space(rdest,rnewcont)\
  93. store_check_dest(&(rdest),&(rnewcont))
  94. #endif /* ivmspace_INCLUDED */