13ff48bf5SDavid du Colombier /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. 27dd7cddfSDavid du Colombier 3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or 4*593dc095SDavid du Colombier implied. 57dd7cddfSDavid du Colombier 6*593dc095SDavid du Colombier This software is distributed under license and may not be copied, 7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms 8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution. 97dd7cddfSDavid du Colombier 10*593dc095SDavid du Colombier For more information about licensing, please refer to 11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on 12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or 13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861. 157dd7cddfSDavid du Colombier */ 167dd7cddfSDavid du Colombier 17*593dc095SDavid du Colombier /* $Id: iref.h,v 1.9 2002/06/16 04:47:10 lpd Exp $ */ 187dd7cddfSDavid du Colombier /* Object structure and type definitions for Ghostscript */ 197dd7cddfSDavid du Colombier 207dd7cddfSDavid du Colombier #ifndef iref_INCLUDED 217dd7cddfSDavid du Colombier # define iref_INCLUDED 227dd7cddfSDavid du Colombier 23*593dc095SDavid du Colombier /* 24*593dc095SDavid du Colombier * Note: this file defines a large number of macros. Many of these are 25*593dc095SDavid du Colombier * only used for internal purposes within this file, to help in the 26*593dc095SDavid du Colombier * definition of other macros or data structures, and should never be 27*593dc095SDavid du Colombier * referenced outside this file. It is intended that all such internal 28*593dc095SDavid du Colombier * macros have names beginning with an underscore (_). 29*593dc095SDavid du Colombier */ 30*593dc095SDavid du Colombier 317dd7cddfSDavid du Colombier /* The typedef for object references */ 323ff48bf5SDavid du Colombier #ifndef ref_DEFINED 337dd7cddfSDavid du Colombier typedef struct ref_s ref; 343ff48bf5SDavid du Colombier # define ref_DEFINED 353ff48bf5SDavid du Colombier #endif 367dd7cddfSDavid du Colombier 373ff48bf5SDavid du Colombier /* 383ff48bf5SDavid du Colombier * Define the type for packed object references. This is opaque here: 393ff48bf5SDavid du Colombier * the details are in ipacked.h. 403ff48bf5SDavid du Colombier */ 417dd7cddfSDavid du Colombier typedef ushort ref_packed; 427dd7cddfSDavid du Colombier 437dd7cddfSDavid du Colombier #define log2_sizeof_ref_packed arch_log2_sizeof_short 447dd7cddfSDavid du Colombier #define sizeof_ref_packed (1 << log2_sizeof_ref_packed) 457dd7cddfSDavid du Colombier 467dd7cddfSDavid du Colombier /* 477dd7cddfSDavid du Colombier * Define the object types. 487dd7cddfSDavid du Colombier * The types marked with @ are composite and hence use the a_space field; 497dd7cddfSDavid du Colombier * objects of all other types must have a_space cleared. 507dd7cddfSDavid du Colombier * The types marked with ! behave differently in the interpreter 517dd7cddfSDavid du Colombier * depending on whether they are executable or literal. 527dd7cddfSDavid du Colombier * The types marked with + use the read/write/execute 537dd7cddfSDavid du Colombier * attributes; the rest only use the executable attribute. 547dd7cddfSDavid du Colombier * The types marked with # use the size field. 553ff48bf5SDavid du Colombier * 563ff48bf5SDavid du Colombier * Note that for the object types that support getinterval (array and 573ff48bf5SDavid du Colombier * string types), there is no way to tell whether a given reference 583ff48bf5SDavid du Colombier * designates an original object or a sub-interval. This is a deliberate 593ff48bf5SDavid du Colombier * design decision. 607dd7cddfSDavid du Colombier */ 617dd7cddfSDavid du Colombier typedef enum { 627dd7cddfSDavid du Colombier 637dd7cddfSDavid du Colombier /* 647dd7cddfSDavid du Colombier * Type 0 must be left unassigned, so that the type (and type_attrs) 657dd7cddfSDavid du Colombier * of a valid ref will never be zero. This speeds up simultaneous 667dd7cddfSDavid du Colombier * type/space checking in def (see dstack.h for details) and a similar 677dd7cddfSDavid du Colombier * check in ref_save (see store.h for details). We may as well use 687dd7cddfSDavid du Colombier * type 0 for t__invalid, which will never appear in a real ref. 697dd7cddfSDavid du Colombier * 707dd7cddfSDavid du Colombier * The "invalid" type is only used in a few special places: the guard 713ff48bf5SDavid du Colombier * entries at the bottom of the o-stack that detect stack underflow, and 723ff48bf5SDavid du Colombier * (perhaps eventually) the ref that the cached value pointer in names 733ff48bf5SDavid du Colombier * points to if the binding isn't known. It never appears on a stack or in 743ff48bf5SDavid du Colombier * a program-visible data structure. 757dd7cddfSDavid du Colombier */ 767dd7cddfSDavid du Colombier 777dd7cddfSDavid du Colombier t__invalid, /* (no value) */ 787dd7cddfSDavid du Colombier t_boolean, /* value.boolval */ 797dd7cddfSDavid du Colombier t_dictionary, /* @ + value.pdict */ 807dd7cddfSDavid du Colombier t_file, /* @!+# value.pfile, uses size for id */ 817dd7cddfSDavid du Colombier 827dd7cddfSDavid du Colombier /* 837dd7cddfSDavid du Colombier * The 4 array types must be kept together, and must start at 847dd7cddfSDavid du Colombier * a multiple of 4, for the sake of r_is_array and r_is_proc (see below). 857dd7cddfSDavid du Colombier */ 867dd7cddfSDavid du Colombier 87*593dc095SDavid du Colombier #define _REF_T_ARRAY_SPAN 4 887dd7cddfSDavid du Colombier t_array, /* @!+# value.refs */ 893ff48bf5SDavid du Colombier /* 903ff48bf5SDavid du Colombier * The following are the two implementations of packed arrays. 913ff48bf5SDavid du Colombier * See ipacked.h for details. 923ff48bf5SDavid du Colombier */ 937dd7cddfSDavid du Colombier t_mixedarray, /* @!+# value.packed */ 947dd7cddfSDavid du Colombier t_shortarray, /* @!+# value.packed */ 957dd7cddfSDavid du Colombier t_unused_array_, /* (an unused array type) */ 967dd7cddfSDavid du Colombier 977dd7cddfSDavid du Colombier /* 987dd7cddfSDavid du Colombier * t_[a]struct is an "umbrella" for other types that are represented by 997dd7cddfSDavid du Colombier * allocated objects (structures). Objects of these types are composite 1007dd7cddfSDavid du Colombier * and hence use the a_local attribute. The type name is taken from 1017dd7cddfSDavid du Colombier * the allocator template for the structure. t_astruct objects use the 1027dd7cddfSDavid du Colombier * access attributes; t_struct objects do not. Neither t_struct nor 1037dd7cddfSDavid du Colombier * t_astruct objects use the size. 1047dd7cddfSDavid du Colombier * 1057dd7cddfSDavid du Colombier * t_struct is currently used for the following PostScript types: 1067dd7cddfSDavid du Colombier * condition, lock. 1077dd7cddfSDavid du Colombier * We could use it for fontIDs, except that they may have subclasses. 1087dd7cddfSDavid du Colombier * Eventually it will also be used for the new 'device' type. 1097dd7cddfSDavid du Colombier * t_astruct is currently used for the following PostScript types: 1107dd7cddfSDavid du Colombier * gstate. 1117dd7cddfSDavid du Colombier * 1127dd7cddfSDavid du Colombier * The 2 structure types must be kept together, and must start at 1137dd7cddfSDavid du Colombier * a multiple of 2, for the sake of r_has_stype (see below). 1147dd7cddfSDavid du Colombier */ 1157dd7cddfSDavid du Colombier 116*593dc095SDavid du Colombier #define _REF_T_STRUCT_SPAN 2 1177dd7cddfSDavid du Colombier t_struct, /* @ value.pstruct */ 1187dd7cddfSDavid du Colombier t_astruct, /* @ + value.pstruct */ 1197dd7cddfSDavid du Colombier 1207dd7cddfSDavid du Colombier /* 1217dd7cddfSDavid du Colombier * We now continue with individual types. 1227dd7cddfSDavid du Colombier */ 1237dd7cddfSDavid du Colombier t_fontID, /* @ value.pstruct */ 1247dd7cddfSDavid du Colombier t_integer, /* value.intval */ 1257dd7cddfSDavid du Colombier t_mark, /* (no value) */ 1267dd7cddfSDavid du Colombier /* 1277dd7cddfSDavid du Colombier * Name objects use the a_space field because they really are composite 1287dd7cddfSDavid du Colombier * objects internally. 1297dd7cddfSDavid du Colombier */ 1307dd7cddfSDavid du Colombier t_name, /* @! # value.pname, uses size for index */ 1317dd7cddfSDavid du Colombier t_null, /* ! # (value.opproc, uses size for mark */ 1327dd7cddfSDavid du Colombier /* type, on e-stack only) */ 1337dd7cddfSDavid du Colombier /* 1347dd7cddfSDavid du Colombier * Operator objects use the a_space field because they may actually be 1357dd7cddfSDavid du Colombier * disguised procedures. (Real operators always have a_space = 0.) 1367dd7cddfSDavid du Colombier */ 1377dd7cddfSDavid du Colombier t_operator, /* @! # value.opproc, uses size for index */ 1387dd7cddfSDavid du Colombier t_real, /* value.realval */ 1397dd7cddfSDavid du Colombier t_save, /* value.saveid, see isave.h for why */ 1407dd7cddfSDavid du Colombier /* this isn't a t_struct */ 1417dd7cddfSDavid du Colombier t_string, /* @!+# value.bytes */ 1427dd7cddfSDavid du Colombier /* 1437dd7cddfSDavid du Colombier * The following are extensions to the PostScript type set. 1447dd7cddfSDavid du Colombier * If you add new types, be sure to edit: 1457dd7cddfSDavid du Colombier * - REF_TYPE_*STRINGS* and REF_TYPE_PROPERTIES_DATA below; 1467dd7cddfSDavid du Colombier * - the table in gs_init.ps (==only operator); 1477dd7cddfSDavid du Colombier * - the printing routine in idebug.c; 1487dd7cddfSDavid du Colombier * - the dispatches in igc.c, igcref.c, and interp.c; 1497dd7cddfSDavid du Colombier * - obj_cvs, obj_cvp, and obj_eq in iutil.c; 1507dd7cddfSDavid du Colombier * - restore_check_stack in zvmem.c. 1517dd7cddfSDavid du Colombier */ 1527dd7cddfSDavid du Colombier t_device, /* @ + value.pdevice */ 1537dd7cddfSDavid du Colombier t_oparray, /* @! # value.const_refs, uses size */ 1547dd7cddfSDavid du Colombier /* for index */ 1557dd7cddfSDavid du Colombier t_next_index /*** first available index ***/ 1567dd7cddfSDavid du Colombier } ref_type; 1577dd7cddfSDavid du Colombier 1587dd7cddfSDavid du Colombier /* 1597dd7cddfSDavid du Colombier * The interpreter uses types starting at t_next_index for representing 1607dd7cddfSDavid du Colombier * a few high-frequency operators. 1617dd7cddfSDavid du Colombier * Since there are no operations specifically on operators, 1627dd7cddfSDavid du Colombier * there is no need for any operators to check specifically for these 1637dd7cddfSDavid du Colombier * types. The r_btype macro takes care of the conversion when required. 1647dd7cddfSDavid du Colombier */ 1657dd7cddfSDavid du Colombier /*extern const int tx_next_index; *//* in interp.c */ 1667dd7cddfSDavid du Colombier /* 1677dd7cddfSDavid du Colombier * Define a table giving properties of types, similar to the table used 1687dd7cddfSDavid du Colombier * by the isxxx functions (macros) in <ctype.h>. 1697dd7cddfSDavid du Colombier */ 170*593dc095SDavid du Colombier #define _REF_TYPE_USES_ACCESS 1 /* type uses w/r/x attributes ("+" above) */ 171*593dc095SDavid du Colombier #define _REF_TYPE_USES_SIZE 2 /* type uses size attribute ("#" above) */ 172*593dc095SDavid du Colombier #define _REF_TYPE_IS_NULL 4 /* type is t_null */ 173*593dc095SDavid du Colombier #define _REF_TYPE_IS_DICTIONARY 8 /* type is t_dictionary */ 1747dd7cddfSDavid du Colombier extern const byte ref_type_properties[1 << 6]; /* r_type_bits */ 1757dd7cddfSDavid du Colombier 1767dd7cddfSDavid du Colombier #define REF_TYPE_PROPERTIES_DATA\ 1777dd7cddfSDavid du Colombier 0, /* t__invalid */\ 1787dd7cddfSDavid du Colombier 0, /* t_boolean */\ 179*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS | _REF_TYPE_IS_DICTIONARY, /* t_dictionary */\ 180*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_file */\ 181*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_array */\ 182*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_mixedarray */\ 183*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_shortarray */\ 184*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* (unused array type) */\ 1857dd7cddfSDavid du Colombier 0, /* t_struct */\ 186*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS, /* t_astruct */\ 1877dd7cddfSDavid du Colombier 0, /* t_fontID */\ 1887dd7cddfSDavid du Colombier 0, /* t_integer */\ 1897dd7cddfSDavid du Colombier 0, /* t_mark */\ 190*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE, /* t_name */\ 191*593dc095SDavid du Colombier _REF_TYPE_IS_NULL, /* t_null, uses size only on e-stack */\ 192*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE, /* t_operator */\ 1937dd7cddfSDavid du Colombier 0, /* t_real */\ 1947dd7cddfSDavid du Colombier 0, /* t_save */\ 195*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_string */\ 196*593dc095SDavid du Colombier _REF_TYPE_USES_ACCESS, /* t_device */\ 197*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE, /* t_oparray */\ 1987dd7cddfSDavid du Colombier /*\ 1997dd7cddfSDavid du Colombier * The remaining types are the extended pseudo-types used by the\ 2007dd7cddfSDavid du Colombier * interpreter for operators. We need to fill up the table.\ 2017dd7cddfSDavid du Colombier */\ 202*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*24*/\ 203*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*28*/\ 204*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*32*/\ 205*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*36*/\ 206*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*40*/\ 207*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*44*/\ 208*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*48*/\ 209*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*52*/\ 210*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*56*/\ 211*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*60*/\ 212*593dc095SDavid du Colombier _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE /*64 */ 213*593dc095SDavid du Colombier #define _REF_TYPE_HAS(rtype,props)\ 2147dd7cddfSDavid du Colombier ((ref_type_properties[rtype] & (props)) != 0) 2157dd7cddfSDavid du Colombier #define ref_type_uses_access(rtype)\ 216*593dc095SDavid du Colombier _REF_TYPE_HAS(rtype, _REF_TYPE_USES_ACCESS) 2177dd7cddfSDavid du Colombier #define ref_type_uses_size(rtype)\ 218*593dc095SDavid du Colombier _REF_TYPE_HAS(rtype, _REF_TYPE_USES_SIZE) 2197dd7cddfSDavid du Colombier #define ref_type_uses_size_or_null(rtype)\ 220*593dc095SDavid du Colombier _REF_TYPE_HAS(rtype, _REF_TYPE_USES_SIZE | _REF_TYPE_IS_NULL) 2217dd7cddfSDavid du Colombier /* 2227dd7cddfSDavid du Colombier * Define the type names for debugging printout. 2237dd7cddfSDavid du Colombier * All names must be the same length, so that columns will line up. 2247dd7cddfSDavid du Colombier */ 2257dd7cddfSDavid du Colombier #define REF_TYPE_DEBUG_PRINT_STRINGS\ 2267dd7cddfSDavid du Colombier "INVL","bool","dict","file",\ 2277dd7cddfSDavid du Colombier "arry","mpry","spry","u?ry",\ 2287dd7cddfSDavid du Colombier "STRC","ASTR",\ 2297dd7cddfSDavid du Colombier "font","int ","mark","name","null",\ 2307dd7cddfSDavid du Colombier "oper","real","save","str ",\ 2317dd7cddfSDavid du Colombier "devc","opry" 2327dd7cddfSDavid du Colombier /* 2337dd7cddfSDavid du Colombier * Define the type names for the type operator. 2347dd7cddfSDavid du Colombier */ 2357dd7cddfSDavid du Colombier #define REF_TYPE_NAME_STRINGS\ 2367dd7cddfSDavid du Colombier 0,"booleantype","dicttype","filetype",\ 2377dd7cddfSDavid du Colombier "arraytype","packedarraytype","packedarraytype","arraytype",\ 2387dd7cddfSDavid du Colombier 0,0,\ 2397dd7cddfSDavid du Colombier "fonttype","integertype","marktype","nametype","nulltype",\ 2407dd7cddfSDavid du Colombier "operatortype","realtype","savetype","stringtype",\ 2417dd7cddfSDavid du Colombier "devicetype","operatortype" 2427dd7cddfSDavid du Colombier /* 2437dd7cddfSDavid du Colombier * Define the type names for obj_cvp (the == operator). We only need these 2447dd7cddfSDavid du Colombier * for types that obj_cvp and obj_cvs don't handle specially. 2457dd7cddfSDavid du Colombier */ 2467dd7cddfSDavid du Colombier #define REF_TYPE_PRINT_STRINGS\ 2477dd7cddfSDavid du Colombier 0,0,"-dict-","-file-",\ 2487dd7cddfSDavid du Colombier "-array-","-packedarray-","-packedarray-","-array-",\ 2497dd7cddfSDavid du Colombier 0,0,\ 2507dd7cddfSDavid du Colombier "-fontID-",0,"-mark-",0,0,\ 2517dd7cddfSDavid du Colombier 0,0,"-save-","-string-",\ 2527dd7cddfSDavid du Colombier "-device-",0 2537dd7cddfSDavid du Colombier 2547dd7cddfSDavid du Colombier /* 2557dd7cddfSDavid du Colombier * The following factors affect the encoding of attributes: 2567dd7cddfSDavid du Colombier * 2577dd7cddfSDavid du Colombier * - The packed array format requires the high-order bits of the 2587dd7cddfSDavid du Colombier * type/attributes field to be 0. (see packed.h) 2597dd7cddfSDavid du Colombier * 2607dd7cddfSDavid du Colombier * - The interpreter wants the type, executable bit, and execute 2617dd7cddfSDavid du Colombier * permission to be adjacent, and in that order from high to low. 2627dd7cddfSDavid du Colombier * 2637dd7cddfSDavid du Colombier * - Type testing is most efficient if the type is in a byte by itself. 2647dd7cddfSDavid du Colombier * 2657dd7cddfSDavid du Colombier * The layout given below results in the most efficient code overall. 2667dd7cddfSDavid du Colombier */ 2677dd7cddfSDavid du Colombier 2683ff48bf5SDavid du Colombier /* 2693ff48bf5SDavid du Colombier * A few of the fields of a ref are associated with the *location*; 2703ff48bf5SDavid du Colombier * most are associated with the ref that is *stored* in that location. 2713ff48bf5SDavid du Colombier * When a ref is copied from one location to another, the former are 2723ff48bf5SDavid du Colombier * preserved in the destination, the latter are copied. 2733ff48bf5SDavid du Colombier */ 2743ff48bf5SDavid du Colombier /* 2753ff48bf5SDavid du Colombier * The following are the attributes associated with the location: 2763ff48bf5SDavid du Colombier */ 2777dd7cddfSDavid du Colombier #define l_mark 1 /* mark for garbage collector */ 2787dd7cddfSDavid du Colombier #define l_new 2 /* stored into since last save */ 2793ff48bf5SDavid du Colombier /* 2803ff48bf5SDavid du Colombier * The following are attributes associated with the ref itself (the 2813ff48bf5SDavid du Colombier * contents of the location). These are visible to PostScript code. 2823ff48bf5SDavid du Colombier */ 2833ff48bf5SDavid du Colombier /* 2843ff48bf5SDavid du Colombier * Reserve bits for VM space information (defined in ivmspace.h). Note that 2853ff48bf5SDavid du Colombier * These bits refer to the VM space of the pointer in the ref, if any, not 2863ff48bf5SDavid du Colombier * the location in which the ref itself is stored. For scalars, these bits 2873ff48bf5SDavid du Colombier * are always zero. 2883ff48bf5SDavid du Colombier */ 2897dd7cddfSDavid du Colombier #define r_space_bits 2 2907dd7cddfSDavid du Colombier #define r_space_shift 2 2913ff48bf5SDavid du Colombier /* 2923ff48bf5SDavid du Colombier * Define the protection attributes. Only 4 combinations are legal: 2933ff48bf5SDavid du Colombier * 0, execute, execute + read, execute + read + write. Note that some 2943ff48bf5SDavid du Colombier * refs (such as scalars) do not use these: in such refs, they are 2953ff48bf5SDavid du Colombier * always zero. 2963ff48bf5SDavid du Colombier */ 2977dd7cddfSDavid du Colombier #define a_write 0x10 2987dd7cddfSDavid du Colombier #define a_read 0x20 2997dd7cddfSDavid du Colombier #define a_execute 0x40 3007dd7cddfSDavid du Colombier #define a_readonly (a_read + a_execute) 3017dd7cddfSDavid du Colombier #define a_all (a_write + a_read+a_execute) 3023ff48bf5SDavid du Colombier /* 3033ff48bf5SDavid du Colombier * Define the executable attribute. All refs use this. 3043ff48bf5SDavid du Colombier */ 3053ff48bf5SDavid du Colombier #define a_executable 0x80 3063ff48bf5SDavid du Colombier /* 3073ff48bf5SDavid du Colombier * Define the bits used for the ref type. See ipacked.h for more 3083ff48bf5SDavid du Colombier * information about the possible values of the type byte. 3093ff48bf5SDavid du Colombier */ 3107dd7cddfSDavid du Colombier #define r_type_shift 8 3117dd7cddfSDavid du Colombier #define r_type_bits 6 3127dd7cddfSDavid du Colombier 313*593dc095SDavid du Colombier /* 314*593dc095SDavid du Colombier * Define the attribute names for debugging printout. 315*593dc095SDavid du Colombier * Each entry has the form <mask, value, character>. 316*593dc095SDavid du Colombier */ 317*593dc095SDavid du Colombier typedef struct ref_attr_print_mask_s { 3187dd7cddfSDavid du Colombier ushort mask; 3197dd7cddfSDavid du Colombier ushort value; 3207dd7cddfSDavid du Colombier char print; 321*593dc095SDavid du Colombier } ref_attr_print_mask_t; 3227dd7cddfSDavid du Colombier 323*593dc095SDavid du Colombier #define _REF_ATTR_PRINT_FLAG(m,c)\ 3247dd7cddfSDavid du Colombier {m,m,c},{m,0,'-'} 325*593dc095SDavid du Colombier #define _REF_ATTR_PRINT_SPACE(v,c)\ 3267dd7cddfSDavid du Colombier {((1<<r_space_bits)-1)<<r_space_shift,v,c} 327*593dc095SDavid du Colombier #define REF_ATTR_PRINT_MASKS\ 328*593dc095SDavid du Colombier _REF_ATTR_PRINT_FLAG(l_mark,'m'),\ 329*593dc095SDavid du Colombier _REF_ATTR_PRINT_FLAG(l_new,'n'),\ 330*593dc095SDavid du Colombier _REF_ATTR_PRINT_SPACE(avm_foreign,'F'),\ 331*593dc095SDavid du Colombier _REF_ATTR_PRINT_SPACE(avm_system,'S'),\ 332*593dc095SDavid du Colombier _REF_ATTR_PRINT_SPACE(avm_global,'G'),\ 333*593dc095SDavid du Colombier _REF_ATTR_PRINT_SPACE(avm_local,'L'),\ 334*593dc095SDavid du Colombier _REF_ATTR_PRINT_FLAG(a_write,'w'),\ 335*593dc095SDavid du Colombier _REF_ATTR_PRINT_FLAG(a_read,'r'),\ 336*593dc095SDavid du Colombier _REF_ATTR_PRINT_FLAG(a_execute,'x'),\ 337*593dc095SDavid du Colombier _REF_ATTR_PRINT_FLAG(a_executable,'e'),\ 338*593dc095SDavid du Colombier _REF_ATTR_PRINT_FLAG(0x4000,'?'),\ 339*593dc095SDavid du Colombier _REF_ATTR_PRINT_FLAG(0x8000,'?') 3407dd7cddfSDavid du Colombier 3417dd7cddfSDavid du Colombier /* Abstract types */ 3427dd7cddfSDavid du Colombier typedef struct dict_s dict; 3437dd7cddfSDavid du Colombier typedef struct name_s name; 3447dd7cddfSDavid du Colombier 3457dd7cddfSDavid du Colombier #ifndef stream_DEFINED 3467dd7cddfSDavid du Colombier # define stream_DEFINED 3477dd7cddfSDavid du Colombier typedef struct stream_s stream; 3487dd7cddfSDavid du Colombier #endif 3497dd7cddfSDavid du Colombier #ifndef gx_device_DEFINED 3507dd7cddfSDavid du Colombier # define gx_device_DEFINED 3517dd7cddfSDavid du Colombier typedef struct gx_device_s gx_device; 3527dd7cddfSDavid du Colombier #endif 3537dd7cddfSDavid du Colombier #ifndef obj_header_DEFINED 3547dd7cddfSDavid du Colombier # define obj_header_DEFINED 3557dd7cddfSDavid du Colombier typedef struct obj_header_s obj_header_t; 3567dd7cddfSDavid du Colombier #endif 3577dd7cddfSDavid du Colombier 3587dd7cddfSDavid du Colombier /* 3597dd7cddfSDavid du Colombier * Define the argument type for operator procedures. Note that the 3607dd7cddfSDavid du Colombier * argument name is not arbitrary: it is used in access macros, so all 3617dd7cddfSDavid du Colombier * operator procedures must use it. 3627dd7cddfSDavid du Colombier */ 3637dd7cddfSDavid du Colombier #ifndef i_ctx_t_DEFINED 3647dd7cddfSDavid du Colombier # define i_ctx_t_DEFINED 3657dd7cddfSDavid du Colombier typedef struct gs_context_state_s i_ctx_t; 3667dd7cddfSDavid du Colombier #endif 367*593dc095SDavid du Colombier typedef int (*op_proc_t)(i_ctx_t *i_ctx_p); 3687dd7cddfSDavid du Colombier /* real_opproc is a holdover.... */ 3697dd7cddfSDavid du Colombier #define real_opproc(pref) ((pref)->value.opproc) 3707dd7cddfSDavid du Colombier 3717dd7cddfSDavid du Colombier /* Object reference */ 3727dd7cddfSDavid du Colombier /* 3737dd7cddfSDavid du Colombier * Note that because of the way packed arrays are represented, 3747dd7cddfSDavid du Colombier * the type_attrs member must be the first one in the ref structure. 3757dd7cddfSDavid du Colombier */ 3767dd7cddfSDavid du Colombier struct tas_s { 377*593dc095SDavid du Colombier /* type_attrs is a single element for fast dispatching in the interpreter */ 3787dd7cddfSDavid du Colombier ushort type_attrs; 3797dd7cddfSDavid du Colombier ushort rsize; 3807dd7cddfSDavid du Colombier }; 3817dd7cddfSDavid du Colombier struct ref_s { 3827dd7cddfSDavid du Colombier 3837dd7cddfSDavid du Colombier struct tas_s tas; 3847dd7cddfSDavid du Colombier 3857dd7cddfSDavid du Colombier union v { /* name the union to keep gdb happy */ 3867dd7cddfSDavid du Colombier long intval; 3877dd7cddfSDavid du Colombier ushort boolval; 3887dd7cddfSDavid du Colombier float realval; 3897dd7cddfSDavid du Colombier ulong saveid; 3907dd7cddfSDavid du Colombier byte *bytes; 3917dd7cddfSDavid du Colombier const byte *const_bytes; 3927dd7cddfSDavid du Colombier ref *refs; 3937dd7cddfSDavid du Colombier const ref *const_refs; 3947dd7cddfSDavid du Colombier name *pname; 3957dd7cddfSDavid du Colombier const name *const_pname; 3967dd7cddfSDavid du Colombier dict *pdict; 3977dd7cddfSDavid du Colombier const dict *const_pdict; 3987dd7cddfSDavid du Colombier /* 3997dd7cddfSDavid du Colombier * packed is the normal variant for referring to packed arrays, 4007dd7cddfSDavid du Colombier * but we need a writable variant for memory management and for 4017dd7cddfSDavid du Colombier * storing into packed dictionary key arrays. 4027dd7cddfSDavid du Colombier */ 4037dd7cddfSDavid du Colombier const ref_packed *packed; 4047dd7cddfSDavid du Colombier ref_packed *writable_packed; 4057dd7cddfSDavid du Colombier op_proc_t opproc; 4067dd7cddfSDavid du Colombier struct stream_s *pfile; 4077dd7cddfSDavid du Colombier struct gx_device_s *pdevice; 4087dd7cddfSDavid du Colombier obj_header_t *pstruct; 4097dd7cddfSDavid du Colombier } value; 4107dd7cddfSDavid du Colombier }; 4117dd7cddfSDavid du Colombier 412*593dc095SDavid du Colombier /* ---------------- Private ref macros ---------------- */ 413*593dc095SDavid du Colombier 414*593dc095SDavid du Colombier /* 415*593dc095SDavid du Colombier * Test whether a ref has a type within a given span, and also has all of a 416*593dc095SDavid du Colombier * given set of attributes. 417*593dc095SDavid du Colombier */ 418*593dc095SDavid du Colombier #define _REF_HAS_MASKED_TYPE_ATTRS(rp,typ,tspan,mask)\ 419*593dc095SDavid du Colombier (((rp)->tas.type_attrs &\ 420*593dc095SDavid du Colombier ((((1 << r_type_bits) - (tspan)) << r_type_shift) + (mask))) ==\ 421*593dc095SDavid du Colombier (((typ) << r_type_shift) + (mask))) 422*593dc095SDavid du Colombier 423*593dc095SDavid du Colombier /* ---------------- Public ref macros ---------------- */ 424*593dc095SDavid du Colombier 425*593dc095SDavid du Colombier /* 426*593dc095SDavid du Colombier * All of these macros take an argument "rp" which is a pointer to a ref. 427*593dc095SDavid du Colombier * Unless otherwise specified, they only apply to full-size (not packed) 428*593dc095SDavid du Colombier * refs. 429*593dc095SDavid du Colombier */ 430*593dc095SDavid du Colombier 431*593dc095SDavid du Colombier /* 432*593dc095SDavid du Colombier * Read, set, increment, and decrement the size field of a ref. 433*593dc095SDavid du Colombier */ 434*593dc095SDavid du Colombier #define r_size(rp) ((rp)->tas.rsize) 435*593dc095SDavid du Colombier #define r_inc_size(rp,inc) ((rp)->tas.rsize += (inc)) 436*593dc095SDavid du Colombier #define r_dec_size(rp,dec) ((rp)->tas.rsize -= (dec)) 437*593dc095SDavid du Colombier #define r_set_size(rp,siz) ((rp)->tas.rsize = (siz)) 438*593dc095SDavid du Colombier 439*593dc095SDavid du Colombier /* 440*593dc095SDavid du Colombier * Get the type of a ref; test whether a ref has a given type. The 441*593dc095SDavid du Colombier * difference between r_type and r_btype is that for refs with types greater 442*593dc095SDavid du Colombier * than or equal to t_next_index, r_type returns that type, but r_btype 443*593dc095SDavid du Colombier * returns t_operator (since those types just encode specific operators for 444*593dc095SDavid du Colombier * faster dispatch in the interpreter -- see interp.h for more information). 445*593dc095SDavid du Colombier */ 446*593dc095SDavid du Colombier #if r_type_shift == 8 447*593dc095SDavid du Colombier # if arch_is_big_endian 448*593dc095SDavid du Colombier # define r_type(rp) (((const byte *)&((rp)->tas.type_attrs))[sizeof(ushort)-2]) 449*593dc095SDavid du Colombier # else 450*593dc095SDavid du Colombier # define r_type(rp) (((const byte *)&((rp)->tas.type_attrs))[1]) 451*593dc095SDavid du Colombier # endif 452*593dc095SDavid du Colombier # define r_has_type(rp,typ) (r_type(rp) == (typ)) 453*593dc095SDavid du Colombier #else 454*593dc095SDavid du Colombier # define r_type(rp) ((rp)->tas.type_attrs >> r_type_shift) 455*593dc095SDavid du Colombier # define r_has_type(rp,typ) r_has_type_attrs(rp,typ,0) /* see below */ 456*593dc095SDavid du Colombier #endif 457*593dc095SDavid du Colombier #define r_btype(rp)\ 458*593dc095SDavid du Colombier ((rp)->tas.type_attrs >= (t_next_index << r_type_shift) ?\ 459*593dc095SDavid du Colombier t_operator : r_type(rp)) 460*593dc095SDavid du Colombier 461*593dc095SDavid du Colombier /* 462*593dc095SDavid du Colombier * Test whether a ref is an array, or a procedure, or a(n) [a]struct. 463*593dc095SDavid du Colombier */ 464*593dc095SDavid du Colombier #define r_is_array(rp)\ 465*593dc095SDavid du Colombier _REF_HAS_MASKED_TYPE_ATTRS(rp,t_array,_REF_T_ARRAY_SPAN,0) 466*593dc095SDavid du Colombier #define r_is_proc(rp)\ 467*593dc095SDavid du Colombier _REF_HAS_MASKED_TYPE_ATTRS(rp,t_array,_REF_T_ARRAY_SPAN,a_execute+a_executable) 468*593dc095SDavid du Colombier #define r_is_struct(rp)\ 469*593dc095SDavid du Colombier _REF_HAS_MASKED_TYPE_ATTRS(rp,t_struct,_REF_T_STRUCT_SPAN,0) 470*593dc095SDavid du Colombier 471*593dc095SDavid du Colombier /* 472*593dc095SDavid du Colombier * Test whether a ref is a struct or astruct with a specific structure type 473*593dc095SDavid du Colombier * (GC descriptor). 474*593dc095SDavid du Colombier */ 475*593dc095SDavid du Colombier #define r_has_stype(rp,mem,styp)\ 476*593dc095SDavid du Colombier (r_is_struct(rp) && gs_object_type(mem, (rp)->value.pstruct) == &styp) 477*593dc095SDavid du Colombier 478*593dc095SDavid du Colombier /* 479*593dc095SDavid du Colombier * Set the type of a ref. This is only used in a few very special places. 480*593dc095SDavid du Colombier * Normally the type of a ref is set when the ref is created (by one of 481*593dc095SDavid du Colombier * the make_xxx macros in store.h) and never changed. 482*593dc095SDavid du Colombier */ 483*593dc095SDavid du Colombier #define r_set_type(rp,typ) ((rp)->tas.type_attrs = (typ) << r_type_shift) 484*593dc095SDavid du Colombier 485*593dc095SDavid du Colombier /* 486*593dc095SDavid du Colombier * Get, test, or set the type and attributes of a ref together as a single 487*593dc095SDavid du Colombier * value. This too is only used in a few special places. 488*593dc095SDavid du Colombier */ 489*593dc095SDavid du Colombier #define r_type_attrs(rp) ((rp)->tas.type_attrs) /* reading only */ 490*593dc095SDavid du Colombier #define r_has_type_attrs(rp,typ,mask)\ 491*593dc095SDavid du Colombier _REF_HAS_MASKED_TYPE_ATTRS(rp,typ,1,mask) 492*593dc095SDavid du Colombier #define r_set_type_attrs(rp,typ,mask)\ 493*593dc095SDavid du Colombier ((rp)->tas.type_attrs = ((typ) << r_type_shift) + (mask)) 494*593dc095SDavid du Colombier 495*593dc095SDavid du Colombier /* 496*593dc095SDavid du Colombier * Get the combined type, a_executable, and a_execute bits of a ref, 497*593dc095SDavid du Colombier * for fast dispatching in the interpreter. 498*593dc095SDavid du Colombier */ 499*593dc095SDavid du Colombier /* 500*593dc095SDavid du Colombier * The r_type_xe macro is used in (and only in) the main interpreter loop, 501*593dc095SDavid du Colombier * where its rp operand may be a ref_packed, not necessarily aligned as 502*593dc095SDavid du Colombier * strictly as a full-size ref. The DEC C compiler, and possibly others, 503*593dc095SDavid du Colombier * may compile code assuming that rp is ref-aligned. Therefore, we 504*593dc095SDavid du Colombier * explicitly cast the pointer to a less-strictly-aligned type. 505*593dc095SDavid du Colombier * In order to convince the compiler, we have to do the cast before 506*593dc095SDavid du Colombier * indexing into the structure. 507*593dc095SDavid du Colombier */ 508*593dc095SDavid du Colombier #define _REF_TYPE_XE_SHIFT (r_type_shift - 2) 509*593dc095SDavid du Colombier #define _REF_TAS_TYPE_XE(tas) ((tas) >> _REF_TYPE_XE_SHIFT) 510*593dc095SDavid du Colombier #define r_type_xe(rp)\ 511*593dc095SDavid du Colombier _REF_TAS_TYPE_XE(((const ushort *)(rp))[offset_of(ref, tas.type_attrs) / sizeof(ushort)]) 512*593dc095SDavid du Colombier #define type_xe_value(typ,xe) _REF_TAS_TYPE_XE(((typ) << r_type_shift) + (xe)) 513*593dc095SDavid du Colombier 514*593dc095SDavid du Colombier /* 515*593dc095SDavid du Colombier * Test whether a ref has a given attribute, or all the given attributes. 516*593dc095SDavid du Colombier */ 517*593dc095SDavid du Colombier #define r_has_attr(rp,mask1) /* optimize 1-bit case */\ 518*593dc095SDavid du Colombier (r_type_attrs(rp) & (mask1)) 519*593dc095SDavid du Colombier #define r_has_attrs(rp,mask) !(~r_type_attrs(rp) & (mask)) 520*593dc095SDavid du Colombier 521*593dc095SDavid du Colombier /* 522*593dc095SDavid du Colombier * Test whether those attributes of a ref selected by a mask have a 523*593dc095SDavid du Colombier * given value. 524*593dc095SDavid du Colombier */ 525*593dc095SDavid du Colombier #define r_has_masked_attrs(rp,attrs,mask)\ 526*593dc095SDavid du Colombier ((r_type_attrs(rp) & (mask)) == (attrs)) 527*593dc095SDavid du Colombier 528*593dc095SDavid du Colombier /* 529*593dc095SDavid du Colombier * Set, clear, store, or copy the attributes of a ref. These are rarely 530*593dc095SDavid du Colombier * needed. Note that, unfortunately, the attrs and mask parameters of 531*593dc095SDavid du Colombier * r_store_attrs are reversed from r_has_masked_attrs. 532*593dc095SDavid du Colombier */ 533*593dc095SDavid du Colombier #define r_set_attrs(rp,mask) ((rp)->tas.type_attrs |= (mask)) 534*593dc095SDavid du Colombier #define r_clear_attrs(rp,mask) ((rp)->tas.type_attrs &= ~(mask)) 535*593dc095SDavid du Colombier #define r_store_attrs(rp,mask,attrs)\ 536*593dc095SDavid du Colombier ((rp)->tas.type_attrs = ((rp)->tas.type_attrs & ~(mask)) | (attrs)) 537*593dc095SDavid du Colombier #define r_copy_attrs(rp,mask,sp)\ 538*593dc095SDavid du Colombier r_store_attrs(rp,mask,(sp)->tas.type_attrs & (mask)) 539*593dc095SDavid du Colombier 540*593dc095SDavid du Colombier /* 541*593dc095SDavid du Colombier * Get or set the pointer field of a struct or astruct ref. The typ 542*593dc095SDavid du Colombier * argument of r_ptr is the (C) type of the structure. 543*593dc095SDavid du Colombier */ 544*593dc095SDavid du Colombier #define r_ptr(rp,typ) ((typ *)((rp)->value.pstruct)) 545*593dc095SDavid du Colombier #define r_set_ptr(rp,ptr) ((rp)->value.pstruct = (obj_header_t *)(ptr)) 546*593dc095SDavid du Colombier 547*593dc095SDavid du Colombier /* ---------------- End of ref macros ---------------- */ 548*593dc095SDavid du Colombier 5497dd7cddfSDavid du Colombier /* Define data for initializing an empty array or string. */ 5507dd7cddfSDavid du Colombier #define empty_ref_data(type, attrs)\ 5517dd7cddfSDavid du Colombier { /*tas*/ { /*type_attrs*/ ((type) << r_type_shift) | (attrs),\ 5527dd7cddfSDavid du Colombier /*rsize*/ 0 } } 5537dd7cddfSDavid du Colombier 5547dd7cddfSDavid du Colombier /* Define the size of a ref. */ 5557dd7cddfSDavid du Colombier #define arch_sizeof_ref sizeof(ref) 5567dd7cddfSDavid du Colombier /* Define the required alignment for refs. */ 5577dd7cddfSDavid du Colombier /* We assume all alignment values are powers of 2. */ 5587dd7cddfSDavid du Colombier #define arch_align_ref_mod\ 5597dd7cddfSDavid du Colombier (((arch_align_long_mod - 1) | (arch_align_float_mod - 1) |\ 5607dd7cddfSDavid du Colombier (arch_align_ptr_mod - 1)) + 1) 5617dd7cddfSDavid du Colombier 5627dd7cddfSDavid du Colombier /* Define the maximum size of an array or a string. */ 5637dd7cddfSDavid du Colombier /* The maximum array size is determined by the fact that */ 5647dd7cddfSDavid du Colombier /* the allocator cannot allocate a block larger than max_uint. */ 5657dd7cddfSDavid du Colombier #define max_array_size (max_ushort & (max_uint / (uint)arch_sizeof_ref)) 5667dd7cddfSDavid du Colombier #define max_string_size max_ushort 5677dd7cddfSDavid du Colombier 5687dd7cddfSDavid du Colombier #endif /* iref_INCLUDED */ 569