1 /* $Header: d:/cvsroot/tads/tads3/vmbif.h,v 1.2 1999/05/17 02:52:29 MJRoberts Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 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 vmbif.h - built-in function interface 12 Function 13 Provides the interface to built-in function sets. 14 15 The host application environment may provide more than one set of 16 built-in functions. Each function set is identified by a universally 17 unique identifier; the program image specifies one or more function 18 sets using these identifiers and maps each set to an image-specific 19 index. At run-time, the byte-code program calls built-in functions 20 by specifying a function set index and a function index within the 21 set. 22 23 A particular function set may use more than one universal identifier, 24 because of version evolution. If new functions are added to a function 25 set, the new function set can continue to use its original universal 26 identifier, as long as the function set continues to provide the 27 original set of functions as a subset of its new vector, and as long 28 as the functions in the original set are at the same index positions 29 in the modified function set. 30 Notes 31 32 Modified 33 12/05/98 MJRoberts - Creation 34 */ 35 36 #ifndef VMBIF_H 37 #define VMBIF_H 38 39 #include "t3std.h" 40 #include "vmglob.h" 41 #include "vmtype.h" 42 43 /* ------------------------------------------------------------------------ */ 44 /* 45 * Image function set table. We maintain one global function set table, 46 * which we create when we load the image file. 47 */ 48 49 class CVmBifTable 50 { 51 public: 52 /* 53 * Create a table with a given number of initial entries. The table 54 * may be expanded in the future if necessary, but if the caller can 55 * predict the maximum number of entries required, we can 56 * preallocate the table at its final size and thus avoid the 57 * overhead and memory fragmentation of expanding the table. 58 */ 59 CVmBifTable(size_t init_entries); 60 61 /* delete the table */ 62 ~CVmBifTable(); 63 64 /* clear all entries from the table */ 65 void clear(); 66 67 /* 68 * Add an entry to the table, given the function set identifier (a 69 * string giving the universally unique name for the function set). 70 * Fills in the next available slot. Throws an error if the 71 * function set is not present in the system. A function set may 72 * not be present because it's a newer version than this 73 * implementation provides, or because this particular host 74 * application environment does not provide the function set. 75 */ 76 void add_entry(const char *func_set_id); 77 78 /* get the total number of entries in the table */ get_count()79 size_t get_count() const { return count_; } 80 81 /* call the given function from the given function set */ 82 void call_func(VMG_ uint set_index, uint func_index, uint argc); 83 84 private: 85 /* 86 * Ensure we have space for a given number of entries, allocating 87 * more if necessary. If we must allocate more space, we'll 88 * increase the current allocation size by at least the given 89 * increment (more if necessary to bring it up to the required 90 * size). 91 */ 92 void ensure_space(size_t entries, size_t increment); 93 94 /* 95 * Add an unresolved function set to the table, or throw an error if 96 * this isn't allowed. If we require resolution of function sets at 97 * load time, this should simply throw an error; otherwise, this 98 * should make a null entry in the function set table so that we can 99 * recognize the missing function set if one of its functions is 100 * ever invoked. 101 */ 102 void add_entry_unresolved(const char *func_set_id); 103 104 /* the table array - we keep an array of pointers */ 105 struct vm_bif_entry_t **table_; 106 107 /* 108 * Name array - this is a list of the global function set names; 109 * each entry corresponds to the entry of the table_ array at the 110 * same index. We use this only for call-time resolution, so that 111 * we can report the name of an unavailable function set when a 112 * function from the unavailable set is invoked. 113 */ 114 char **names_; 115 116 /* number of entries defined in the table */ 117 size_t count_; 118 119 /* number of entries allocated for the table */ 120 size_t alloc_; 121 }; 122 123 /* ------------------------------------------------------------------------ */ 124 /* 125 * Function set table entry. This contains information on the function 126 * set at one index in the table. 127 */ 128 struct vm_bif_entry_t 129 { 130 /* 131 * Function set identifier - a string of 7-bit ASCII characters, one 132 * byte per character, in the range 32 to 126 inclusive, of length 1 133 * to 255 characters, null-terminated. 134 */ 135 const char *func_set_id; 136 137 /* number of functions in the function set */ 138 size_t func_count; 139 140 /* 141 * Function vector. Each function has a common C interface, because 142 * the functions take arguments and return values on the VM stack. 143 * The order of the functions within the vector is defined by the 144 * function set specification; a function set which uses a 145 * particular universal identifier must always conform to the 146 * specification for that universal identifier. 147 * 148 * For each function, 'argc' is the number of actual parameters 149 * passed to the function by the caller. The function receives its 150 * parameters from the VM stack; the first argument is at the top of 151 * the stack, the second argument is the next item on the stack, and 152 * so on. The function must remove all of the arguments from the 153 * stack before returning, and must push a return value if 154 * appropriate. 155 */ 156 void (**func)(VMG_ uint argc); 157 }; 158 159 /* ------------------------------------------------------------------------ */ 160 /* 161 * Base class for function set collections. This class provides some 162 * utility functions that intrinsics might find useful. 163 */ 164 class CVmBif 165 { 166 public: 167 /* 168 * check arguments; throws an error if the argument count doesn't 169 * match the given value 170 */ 171 static void check_argc(VMG_ uint argc, uint needed_argc); 172 173 /* 174 * check arguments; throws an error if the argument count is outside 175 * of the given range 176 */ 177 static void check_argc_range(VMG_ uint argc, 178 uint argc_min, uint argc_max); 179 180 /* pop an integer/long value */ 181 static int pop_int_val(VMG0_); 182 static int pop_long_val(VMG0_); 183 184 /* pop a true/nil logical value */ 185 static int pop_bool_val(VMG0_); 186 187 /* pop an object ID value */ 188 static vm_obj_id_t pop_obj_val(VMG0_); 189 190 /* pop a property ID value */ 191 static vm_prop_id_t pop_propid_val(VMG0_); 192 193 /* 194 * Pop a string or list value, returning a pointer to the 195 * string/list data. If the value is a constant string or constant 196 * list, as appropriate, we'll return the constant pool pointer; if 197 * the value is an object of metaclass String or List, as 198 * appropriate, we'll return the metaclass data. Throws an error if 199 * the value is of any other type. 200 */ 201 static const char *pop_str_val(VMG0_); 202 static const char *pop_list_val(VMG0_); 203 204 /* 205 * Pop a null-terminated string into the given buffer. If the 206 * string is too long for the buffer, we'll truncate it to the given 207 * size. 208 */ 209 static void pop_str_val_buf(VMG_ char *buf, size_t buflen); 210 211 /* 212 * Pop a null-terminated string into the given buffer, converting 213 * the string to the filename character set. Null-terminates the 214 * resulting string. 215 */ 216 static void pop_str_val_fname(VMG_ char *buf, size_t buflen); 217 218 /* 219 * Pop a null-terminated string into the given buffer, converting 220 * the string to the UI character set. Null-terminates the 221 * resulting string. 222 */ 223 static void pop_str_val_ui(VMG_ char *buf, size_t buflen); 224 225 /* 226 * Return a value 227 */ 228 static void retval(VMG_ const struct vm_val_t *val); 229 static void retval_nil(VMG0_); 230 static void retval_true(VMG0_); 231 static void retval_bool(VMG_ int val); 232 static void retval_int(VMG_ long val); 233 static void retval_obj(VMG_ vm_obj_id_t obj); 234 static void retval_prop(VMG_ vm_prop_id_t prop); 235 static void retval_str(VMG_ const char *str); 236 static void retval_str(VMG_ const char *str, size_t len); 237 static void retval_fnptr(VMG_ pool_ofs_t func); 238 }; 239 240 241 #endif /* VMBIF_H */ 242 243