cfad47cfa3/tads3/vmbif.h

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
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 */
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 the
220
     *   string to the UI character set.  Null-terminates the resulting
221
     *   string.  If the given buffer is null, we'll allocate a buffer with
222
     *   t3malloc() and return it; the caller is responsible for freeing the
223
     *   buffer with t3free().  In any case, returns the buffer into which we
224
     *   store the results.  
225
     */
226
    static char *pop_str_val_ui(VMG_ char *buf, size_t buflen);
227
228
    /* create a string object from a C-style string in the UI character set */
229
    static vm_obj_id_t str_from_ui_str(VMG_ const char *str);
230
    static vm_obj_id_t str_from_ui_str(VMG_ const char *str, size_t len);
231
    
232
    /*
233
     *   Return a value 
234
     */
235
    static void retval(VMG_ const struct vm_val_t *val);
236
    static void retval_nil(VMG0_);
237
    static void retval_true(VMG0_);
238
    static void retval_bool(VMG_ int val);
239
    static void retval_int(VMG_ long val);
240
    static void retval_obj(VMG_ vm_obj_id_t obj);
241
    static void retval_prop(VMG_ vm_prop_id_t prop);
242
    static void retval_str(VMG_ const char *str);
243
    static void retval_str(VMG_ const char *str, size_t len);
244
    static void retval_ui_str(VMG_ const char *str);
245
    static void retval_ui_str(VMG_ const char *str, size_t len);
246
    static void retval_fnptr(VMG_ pool_ofs_t func);
247
};
248
249
250
#endif /* VMBIF_H */
251