| | 1 | /* $Header$ */ |
| | 2 | |
| | 3 | /* |
| | 4 | * Copyright (c) 2001, 2002 Michael J. Roberts. All Rights Reserved. |
| | 5 | * |
| | 6 | * Please see the accompanying license file, LICENSE.TXT, for information |
| | 7 | * on using and copying this software. |
| | 8 | */ |
| | 9 | /* |
| | 10 | Name |
| | 11 | vmrunsym.h - run-time global symbol table |
| | 12 | Function |
| | 13 | Defines a symbol table structure that allows us to convey the global |
| | 14 | symbols from the compiler or image loader to the interpreter. |
| | 15 | |
| | 16 | When the compiler runs pre-initialization, or when the image loader |
| | 17 | finds debug symbols in a program, the interpreter builds a LookupTable |
| | 18 | object containing the global symbol table. This provides a "reflection" |
| | 19 | mechanism that lets the running program inspect its own symbol table. |
| | 20 | |
| | 21 | Because we have two very different ways of getting the symbol |
| | 22 | information -- from the compiler, or from the image file's debug records |
| | 23 | -- we define this class as an intermediary provide a common mechanism for |
| | 24 | conveying the information to the interpreter. Note that, when the |
| | 25 | information is coming from the compiler, there is usually not a debug |
| | 26 | symbol table in the image file, because the compiler usually only runs |
| | 27 | pre-initialization on programs compiled for release (i.e., with no debug |
| | 28 | information), so we can't count on debug records in the image file as a |
| | 29 | common conveyance mechanism. |
| | 30 | |
| | 31 | This is a very simple linked list storage class, because we have no |
| | 32 | need to search this symbol table. The only things we do with this type of |
| | 33 | symbol table are to load it with all of the symbols from the compiler or |
| | 34 | image file's debug records, and then enumerate all of our symbols to build |
| | 35 | a run-time LookupTable. |
| | 36 | |
| | 37 | One final note: we could conceivably avoid having this other data |
| | 38 | representation by having the compiler build a LookupTable directly and |
| | 39 | storing it in the image file. However, this would put the LookupTable |
| | 40 | into the root set, so it could never be deleted. By building the |
| | 41 | LookupTable dynamically during pre-initialization, the table will be |
| | 42 | automatically garbage collected before the image file is finalized if the |
| | 43 | program doesn't retain a reference to it in a location accessible from the |
| | 44 | root set. This allows the program to control the presence of this extra |
| | 45 | information in a very natural way. |
| | 46 | Notes |
| | 47 | |
| | 48 | Modified |
| | 49 | 02/17/01 MJRoberts - Creation |
| | 50 | */ |
| | 51 | |
| | 52 | #ifndef VMRUNSYM_H |
| | 53 | #define VMRUNSYM_H |
| | 54 | |
| | 55 | #include "vmtype.h" |
| | 56 | |
| | 57 | class CVmRuntimeSymbols |
| | 58 | { |
| | 59 | public: |
| | 60 | /* construct */ |
| | 61 | CVmRuntimeSymbols() |
| | 62 | { |
| | 63 | /* nothing in the list yet - empty the list and clear the count */ |
| | 64 | head_ = tail_ = 0; |
| | 65 | cnt_ = 0; |
| | 66 | } |
| | 67 | |
| | 68 | /* delete */ |
| | 69 | ~CVmRuntimeSymbols(); |
| | 70 | |
| | 71 | /* add a symbol */ |
| | 72 | void add_sym(const char *sym, size_t len, const vm_val_t *val); |
| | 73 | |
| | 74 | /* get the first symbol */ |
| | 75 | struct vm_runtime_sym *get_head() const { return head_; } |
| | 76 | |
| | 77 | /* get the number of symbols */ |
| | 78 | size_t get_sym_count() const { return cnt_; } |
| | 79 | |
| | 80 | /* find an object name - returns null if the object isn't found */ |
| | 81 | const char *find_obj_name(VMG_ vm_obj_id_t obj, size_t *name_len) const |
| | 82 | { |
| | 83 | vm_val_t val; |
| | 84 | |
| | 85 | /* set up an object value */ |
| | 86 | val.set_obj(obj); |
| | 87 | |
| | 88 | /* find the value */ |
| | 89 | return find_val_name(vmg_ &val, name_len); |
| | 90 | } |
| | 91 | |
| | 92 | /* find a property name - returns null if not found */ |
| | 93 | const char *find_prop_name(VMG_ vm_prop_id_t prop, size_t *name_len) const |
| | 94 | { |
| | 95 | vm_val_t val; |
| | 96 | |
| | 97 | /* set up a property ID value */ |
| | 98 | val.set_propid(prop); |
| | 99 | |
| | 100 | /* find the value */ |
| | 101 | return find_val_name(vmg_ &val, name_len); |
| | 102 | } |
| | 103 | |
| | 104 | /* |
| | 105 | * Find the name for a value. Fills in the length pointer with the |
| | 106 | * length of the return string, which is not null-terminated. |
| | 107 | * Returns null if no such value is present in the table. |
| | 108 | */ |
| | 109 | const char *find_val_name(VMG_ const vm_val_t *val, |
| | 110 | size_t *name_len) const; |
| | 111 | |
| | 112 | protected: |
| | 113 | /* head and tail of symbol list */ |
| | 114 | struct vm_runtime_sym *head_; |
| | 115 | struct vm_runtime_sym *tail_; |
| | 116 | |
| | 117 | /* number of symbols in the list */ |
| | 118 | size_t cnt_; |
| | 119 | }; |
| | 120 | |
| | 121 | /* |
| | 122 | * A Symbol |
| | 123 | */ |
| | 124 | struct vm_runtime_sym |
| | 125 | { |
| | 126 | /* next symbol in the list */ |
| | 127 | vm_runtime_sym *nxt; |
| | 128 | |
| | 129 | /* the value of the symbol */ |
| | 130 | vm_val_t val; |
| | 131 | |
| | 132 | /* the length of the name */ |
| | 133 | size_t len; |
| | 134 | |
| | 135 | /* |
| | 136 | * the name - the structure is overallocated to make room for the full |
| | 137 | * text of the name here |
| | 138 | */ |
| | 139 | char sym[1]; |
| | 140 | }; |
| | 141 | |
| | 142 | #endif /* VMRUNSYM_H */ |
| | 143 | |