1 /****************************************************************************
2  * Copyright (C) 2008 by Matteo Franchin                                    *
3  *                                                                          *
4  * This file is part of Box.                                                *
5  *                                                                          *
6  *   Box is free software: you can redistribute it and/or modify it         *
7  *   under the terms of the GNU Lesser General Public License as published  *
8  *   by the Free Software Foundation, either version 3 of the License, or   *
9  *   (at your option) any later version.                                    *
10  *                                                                          *
11  *   Box is distributed in the hope that it will be useful,                 *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
14  *   GNU Lesser General Public License for more details.                    *
15  *                                                                          *
16  *   You should have received a copy of the GNU Lesser General Public       *
17  *   License along with Box.  If not, see <http://www.gnu.org/licenses/>.   *
18  ****************************************************************************/
19 
20 /**
21  * @file vmproc.h
22  * @brief The procedure manager for the Box VM.
23  *
24  * Here we define the procedure manager for the Box virtual machine. These
25  * functions allow to define new procedures, to install them and to manipulate
26  * them in many ways.
27  */
28 
29 #ifndef _BOX_VMPROC_H
30 #  define _BOX_VMPROC_H
31 
32 #  include <stdlib.h>
33 #  include <stdio.h>
34 
35 #  include <box/vm.h>
36 #  include <box/callable.h>
37 
38 /**
39  * Initialize the procedure table.
40  *
41  * @param vmp is the VM-program.
42  */
43 void BoxVM_Proc_Init(BoxVM *vmp);
44 
45 /** Destroy the table of installed and uninstalled procedures.
46  * @param vmp is the VM-program.
47  */
48 void BoxVM_Proc_Finish(BoxVM *vmp);
49 
50 /** Creates a new procedure. A procedure is a place where to put
51  * the assembly code (bytecode) produced by VM_Assemble and is identified
52  * by an integer assigned by this function, which is returned.
53  */
54 BoxVMProcID BoxVM_Proc_Code_New(BoxVM *vm);
55 
56 /** Destroys the procedure whose number is 'proc_num'.
57  */
58 void BoxVM_Proc_Code_Destroy(BoxVM *vm, BoxVMProcID proc_id);
59 
60 /** Return a string that may serve to the user to identify the procedure */
61 char *BoxVM_Proc_Get_Description(BoxVM *vm, BoxVMCallNum call_num);
62 
63 /** Set 'proc_num' to be the target procedure: the place where
64  * VM_Assemble puts the assembled code
65  * NOTE: return 0, if a target procedure has not been set, yet.
66  *   If proc_num == 0, unset the target.
67  */
68 BoxVMProcID BoxVM_Proc_Target_Set(BoxVM *vm, BoxVMProcID proc_num);
69 
70 /** Get the ID of the target procedure */
71 BoxVMProcID BoxVM_Proc_Target_Get(BoxVM *vm);
72 
73 /** Remove all the code assembled inside the procedure 'proc_id'.
74  * WARNING: Labels and their references are not removed!
75  */
76 void BoxVM_Proc_Empty(BoxVM *vm, BoxVMProcID proc_id);
77 
78 /** Returns the call-number which will be assigned to the next installed
79  * procedure.
80  */
81 BoxVMProcID BoxVM_Proc_Get_ID(BoxVM *vm, BoxVMCallNum call_num);
82 
83 size_t BoxVM_Proc_Get_Size(BoxVM *vm, BoxVMProcID id);
84 
85 /**
86  * @brief Allocate a new call number.
87  *
88  * Allocate a new call number in the given VM. This call number can be used to
89  * generate VM code which calls a VM procedure without having to provide an
90  * implementation, first. Obviously, the VM code which is generated in this way
91  * cannot be used (executed) until the call number is implemented (using
92  * BoxVM_Install_Proc_Code() or BoxVM_Install_Proc_Callable()).
93  *
94  * @param vm The virtual machine.
95  * @return A new call number for @p vm.
96  */
97 BOXEXPORT BoxVMCallNum
98 BoxVM_Allocate_Call_Num(BoxVM *vm);
99 
100 /**
101  * @brief Deallocate the most recently allocated call number.
102  *
103  * Deallocate the last call number allocated with BoxVM_Allocate_Call_Num().
104  * The call number must be unused. @p num is required just for consistency
105  * check.
106  * @param vm The virtual machine.
107  * @param The call to be deallocated, which should also be the last allocated
108  *   one.
109  * @return Whether the operation was successful.
110  */
111 BOXEXPORT BoxBool
112 BoxVM_Deallocate_Call_Num(BoxVM *vm, BoxVMCallNum num);
113 
114 /**
115  * @brief Install a procedure from VM code.
116  */
117 BOXEXPORT BoxBool
118 BoxVM_Install_Proc_Code(BoxVM *vm, BoxVMCallNum call_num, BoxVMProcID id);
119 
120 /**
121  * @brief Installs the given C function as a new procedure.
122  *
123  * Similar to BoxVM_Install_Proc_Code(), but installs the given C-function
124  * @p c_proc as a new procedure. The call-number is returned in
125  *   <tt>*call_num</tt>.
126  * @param vm The virtual machine.
127  * @param cn The call number used for installing the code. This is the number
128  *   which can be used to call the procedure from bytecode.
129  * @param c_proc The implementation of the procedure in C.
130  * @return Whether the operation was successful.
131  */
132 BOXEXPORT BoxBool
133 BoxVM_Install_Proc_CCode(BoxVM *vm, BoxVMCallNum cn, BoxCCallOld c_proc);
134 
135 /**
136  * @brief Installs the given callable as a new procedure.
137  *
138  * Similar to BoxVM_Install_Proc_Code(), but installs the given callable
139  * @p cb as a new procedure. The call-number is returned in <tt>*call_num</tt>.
140  * @param vm The virtual machine.
141  * @param cn The call number used for installing the code. This is the number
142  *   which can be used to call the procedure from bytecode.
143  * @param cb A callable object.
144  * @return Whether the operation was successful.
145  */
146 BOXEXPORT BoxBool
147 BoxVM_Install_Proc_Callable(BoxVM *vm, BoxVMCallNum cn, BoxCallable *cb);
148 
149 /**
150  * @brief Set the names for an installed procedure.
151  *
152  * @param vm The virtual machine.
153  * @param cn The call number @p name and @p desc refer to.
154  * @param name The name of the procedure.
155  * @param desc The description of the procedure.
156  * @return Whether the operation was successful.
157  */
158 BOXEXPORT BoxBool
159 BoxVM_Set_Proc_Names(BoxVM *vm, BoxVMCallNum cn,
160                      const char *name, const char *desc);
161 
162 /**
163  * @brief Return the procedure kind for the given call number.
164  *
165  * @param vm The virtual machine to which @p cn refers to.
166  * @param cn The call number for the queried procedure.
167  * @return If the procedure is installed (with BoxVM_Install_Proc_CCode()
168  *   or friends) then return a #BoxVMProcKind corresponding to the procedure
169  *   kind, otherwise return @c BOXVMPROCKIND_UNDEFINED.
170  */
171 BOXEXPORT BoxVMProcKind
172 BoxVM_Get_Proc_Kind(BoxVM *vm, BoxVMCallNum cn);
173 
174 /**
175  * @brief Get the callable associated to a foreign procedure.
176  */
177 BOXEXPORT BoxBool
178 BoxVM_Get_Callable_Implem(BoxVM *vm, BoxVMCallNum cn, BoxCallable **code);
179 
180 
181 #if 0
182 /**
183  * @brief Get
184  */
185 BOXEXPORT BoxBool
186 BoxVM_Get_Code_Implem(BoxVM *vm, BoxVMCallNum cn, BoxCode **code);
187 
188 
189 /**
190  * @brief Define the signature for a call number.
191  *
192  * Provide the procedure signature (input and output types) for a call number
193  * @p cn of the given VM @p vm.
194  *
195  * @param vm The virtual machines the call number refers to.
196  * @param cn The call number to define.
197  * @param cb A callable containing the signature of the call number.
198  * @return Whether the operation was successful.
199  * @note The callable @p cb may be undefined. The actual implementation of
200  *   @p cb is ignored. Use BoxVM_Implement_Call_From_Code() or
201  *   BoxVM_Implement_Call_From_Callable() to provide the implementation.
202  */
203 BOXEXPORT BoxBool
204 BoxVM_Define_Call(BoxVM *vm, BoxVMCallNum cn, BoxCallable *cb);
205 
206 /**
207  * @brief Whether a given call number has been defined in the specified VM.
208  *
209  * @param vm The virtual machines the call number refers to.
210  * @param cn The call number.
211  * @return Whether @p cb has been defined with BoxVM_Define_Call().
212  */
213 BOXEXPORT BoxBool
214 BoxVM_Call_Is_Defined(BoxVM *vm, BoxVMCallNum cn);
215 
216 /**
217  * @brief Provide a VM code implementation for a call number.
218  *
219  * @param vm The virtual machine the call number @p cn refers to.
220  * @param cn The call number to be implemented.
221  * @param code The #BoxVMCode object containing the implementation.
222  * @return Whether the operation was completed successfully.
223  */
224 BOXEXPORT BoxBool
225 BoxVM_Implement_Call_From_Code(BoxVM *vm, BoxVMCallNum cn, BoxVMCode *code);
226 
227 /**
228  * @brief Provide a generic #BoxCallable implementation for a call number.
229  *
230  * @param vm The virtual machine the call number @p cn refers to.
231  * @param cn The call number to be implemented.
232  * @param cb The callable containing the implementation.
233  * @return Whether the operation was completed successfully.
234  */
235 BOXEXPORT BoxBool
236 BoxVM_Implement_Call_From_Callable(BoxVM *vm, BoxVMCallNum cn,
237                                    BoxCallable *cb);
238 
239 /**
240  * @brief Get the callable corresponding to a given call number.
241  *
242  * @param vm VM the call number @p cb refers to.
243  * @param cn The call number.
244  * @return The callable corresponding to the given call number @p cb.
245  */
246 BOXEXPORT BoxCallable *
247 BoxVM_Get_Callable(BoxVM *vm, BoxVMCallNum cn);
248 #endif
249 
250 
251 
252 
253 
254 
255 
256 
257 
258 
259 
260 
261 
262 
263 
264 /** Get the pointer to the bytecode of the procedure 'proc_num' and its
265  * length, expressed as number of BoxVMWord elements.
266  * The information is stored inside *ptr, and *length.
267  * If one of these pointer is NULL, then the corresponding information
268  * is not written.
269  */
270 void BoxVM_Proc_Get_Ptr_And_Length(BoxVM *vmp, BoxVMWord **ptr,
271                                    BoxUInt *length, BoxVMProcID proc_id);
272 
273 /** Print as plain text the code contained inside the procedure 'proc_num'.
274  * The stream out is the destination for the produced output.
275  */
276 BoxTask
277 BoxVM_Proc_Disassemble(BoxVM *vmp, FILE *out, BoxVMProcID proc_num);
278 
279 /** This function prints information and assembly source code
280  * of the procedure, whose number is 'call_num'.
281  * It is similar to VM_Proc_Disassemble, but gives some more details.
282  * @see VM_Proc_Disassemble
283  */
284 BoxTask
285 BoxVM_Proc_Disassemble_One(BoxVM *vmp, FILE *out, BoxVMCallNum call_num);
286 
287 /** This function prints the assembly source code
288  * of all the installed modules.
289  */
290 BoxTask
291 BoxVM_Proc_Disassemble_All(BoxVM *vmp, FILE *out);
292 
293 /** Associate the given position in the source file 'sp' with the current
294  * position in the procedure so that it can be later retrieved with
295  * BoxVM_Proc_Get_Source_Of.
296  * @see BoxVM_Proc_Get_Source_Of
297  */
298 void BoxVM_Proc_Associate_Source(BoxVM *vm, BoxVMProcID id, BoxSrcPos *sp);
299 
300 /** Retrieve the position in the source corresponding to the given position
301  * 'op' in the procedure 'id'.
302  */
303 BoxSrcPos *BoxVM_Proc_Get_Source_Of(BoxVM *vm, BoxVMProcID id, BoxOutPos op);
304 
305 #endif /* _BOX_VMPROC_H */
306