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