CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Path: gap4r8 / src / calls.h
Views: 418346
1
/****************************************************************************
2
**
3
*W calls.h GAP source Martin Schönert
4
**
5
**
6
*Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany
7
*Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
8
*Y Copyright (C) 2002 The GAP Group
9
**
10
** This file declares the functions of the generic function call mechanism
11
** package.
12
**
13
** This package defines the *call mechanism* through which one GAP function,
14
** named the *caller*, can temporarily transfer control to another function,
15
** named the *callee*.
16
**
17
** There are *compiled functions* and *interpreted functions*. Thus there
18
** are four possible pairings of caller and callee.
19
**
20
** If the caller is compiled, then the call comes directly from the caller.
21
** If it is interpreted, then the call comes from one of the functions
22
** 'EvalFunccall<i>args' that implement evaluation of function calls.
23
**
24
** If the callee is compiled, then the call goes directly to the callee.
25
** If it is interpreted, then the call goes to one of the handlers
26
** 'DoExecFunc<i>args' that implement execution of function bodies.
27
**
28
** The call mechanism makes it in any case unneccessary for the calling code
29
** to know whether the callee is a compiled or an interpreted function.
30
** Likewise the called code need not know, actually cannot know, whether the
31
** caller is a compiled or an interpreted function.
32
**
33
** Also the call mechanism checks that the number of arguments passed by the
34
** caller is the same as the number of arguments expected by the callee, or
35
** it collects the arguments in a list if the callee allows a variable
36
** number of arguments.
37
**
38
** Finally the call mechanism profiles all functions if requested.
39
**
40
** All this has very little overhead. In the case of one compiled function
41
** calling another compiled function, which expects fewer than 4 arguments,
42
** with no profiling, the overhead is only a couple of instructions.
43
*/
44
45
#ifndef GAP_CALLS_H
46
#define GAP_CALLS_H
47
48
49
/****************************************************************************
50
**
51
52
*T ObjFunc . . . . . . . . . . . . . . . . type of function returning object
53
**
54
** 'ObjFunc' is the type of a function returning an object.
55
*/
56
typedef Obj (* ObjFunc) (/*arguments*/);
57
58
typedef Obj (* ObjFunc_0ARGS) (Obj self);
59
typedef Obj (* ObjFunc_1ARGS) (Obj self, Obj a1);
60
typedef Obj (* ObjFunc_2ARGS) (Obj self, Obj a1, Obj a2);
61
typedef Obj (* ObjFunc_3ARGS) (Obj self, Obj a1, Obj a2, Obj a3);
62
typedef Obj (* ObjFunc_4ARGS) (Obj self, Obj a1, Obj a2, Obj a3, Obj a4);
63
typedef Obj (* ObjFunc_5ARGS) (Obj self, Obj a1, Obj a2, Obj a3, Obj a4, Obj a5);
64
typedef Obj (* ObjFunc_6ARGS) (Obj self, Obj a1, Obj a2, Obj a3, Obj a4, Obj a5, Obj a6);
65
66
67
/****************************************************************************
68
**
69
*F HDLR_FUNC(<func>,<i>) . . . . . . . . . <i>-th call handler of a function
70
*F NAME_FUNC(<func>) . . . . . . . . . . . . . . . . . . name of a function
71
*F NARG_FUNC(<func>) . . . . . . . . . . . number of arguments of a function
72
*F NAMS_FUNC(<func>) . . . . . . . . names of local variables of a function
73
*F NAMI_FUNC(<func>) . . . . . . name of <i>-th local variable of a function
74
*F PROF_FUNC(<func>) . . . . . . . . profiling information bag of a function
75
*F NLOC_FUNC(<func>) . . . . . . . . . . . . number of locals of a function
76
*F BODY_FUNC(<func>) . . . . . . . . . . . . . . . . . . body of a function
77
*F ENVI_FUNC(<func>) . . . . . . . . . . . . . . . environment of a function
78
*F FEXS_FUNC(<func>) . . . . . . . . . . . . func. expr. list of a function
79
*V SIZE_FUNC . . . . . . . . . . . . . . . . . size of the bag of a function
80
**
81
** These macros make it possible to access the various components of a
82
** function.
83
**
84
** 'HDLR_FUNC(<func>,<i>)' is the <i>-th handler of the function <func>.
85
**
86
** 'NAME_FUNC(<func>)' is the name of the function.
87
**
88
** 'NARG_FUNC(<func>)' is the number of arguments (-1 if <func> accepts a
89
** variable number of arguments).
90
**
91
** 'NAMS_FUNC(<func>)' is the list of the names of the local variables,
92
**
93
** 'NAMI_FUNC(<func>,<i>)' is the name of the <i>-th local variable.
94
**
95
** 'PROF_FUNC(<func>)' is the profiling information bag.
96
**
97
** 'NLOC_FUNC(<func>)' is the number of local variables of the interpreted
98
** function <func>.
99
**
100
** 'BODY_FUNC(<func>)' is the body.
101
**
102
** 'ENVI_FUNC(<func>)' is the environment (i.e., the local variables bag
103
** that was current when <func> was created).
104
**
105
** 'FEXS_FUNC(<func>)' is the function expressions list (i.e., the list of
106
** the function expressions of the functions defined inside of <func>).
107
**
108
*/
109
#define HDLR_FUNC(func,i) (* (ObjFunc*) (ADDR_OBJ(func) + 0 +(i)) )
110
#define NAME_FUNC(func) (* (ADDR_OBJ(func) + 8 ) )
111
#define NARG_FUNC(func) (* (Int*) (ADDR_OBJ(func) + 9 ) )
112
#define NAMS_FUNC(func) (* (ADDR_OBJ(func) +10 ) )
113
#define NAMI_FUNC(func,i) ((Char *)CHARS_STRING(ELM_LIST(NAMS_FUNC(func),i)))
114
#define PROF_FUNC(func) (* (ADDR_OBJ(func) +11 ) )
115
#define NLOC_FUNC(func) (* (UInt*) (ADDR_OBJ(func) +12 ) )
116
#define BODY_FUNC(func) (* (ADDR_OBJ(func) +13 ) )
117
#define ENVI_FUNC(func) (* (ADDR_OBJ(func) +14 ) )
118
#define FEXS_FUNC(func) (* (ADDR_OBJ(func) +15 ) )
119
#define SIZE_FUNC (16*sizeof(Bag))
120
121
#define HDLR_0ARGS(func) ((ObjFunc_0ARGS)HDLR_FUNC(func,0))
122
#define HDLR_1ARGS(func) ((ObjFunc_1ARGS)HDLR_FUNC(func,1))
123
#define HDLR_2ARGS(func) ((ObjFunc_2ARGS)HDLR_FUNC(func,2))
124
#define HDLR_3ARGS(func) ((ObjFunc_3ARGS)HDLR_FUNC(func,3))
125
#define HDLR_4ARGS(func) ((ObjFunc_4ARGS)HDLR_FUNC(func,4))
126
#define HDLR_5ARGS(func) ((ObjFunc_5ARGS)HDLR_FUNC(func,5))
127
#define HDLR_6ARGS(func) ((ObjFunc_6ARGS)HDLR_FUNC(func,6))
128
#define HDLR_XARGS(func) ((ObjFunc_1ARGS)HDLR_FUNC(func,7))
129
130
extern Obj NargError(Obj func, Int actual);
131
132
/****************************************************************************
133
**
134
*F IS_FUNC( <obj> ) . . . . . . . . . . . . . check if object is a function
135
*/
136
#define IS_FUNC(obj) (TNUM_OBJ(obj) == T_FUNCTION)
137
138
139
/****************************************************************************
140
**
141
142
*F CALL_0ARGS(<func>) . . . . . . . . . call a function with 0 arguments
143
*F CALL_1ARGS(<func>,<arg1>) . . . . . . call a function with 1 arguments
144
*F CALL_2ARGS(<func>,<arg1>...) . . . . call a function with 2 arguments
145
*F CALL_3ARGS(<func>,<arg1>...) . . . . call a function with 3 arguments
146
*F CALL_4ARGS(<func>,<arg1>...) . . . . call a function with 4 arguments
147
*F CALL_5ARGS(<func>,<arg1>...) . . . . call a function with 5 arguments
148
*F CALL_6ARGS(<func>,<arg1>...) . . . . call a function with 6 arguments
149
*F CALL_XARGS(<func>,<args>) . . . . . . call a function with more arguments
150
**
151
** 'CALL_<i>ARGS' passes control to the function <func>, which must be a
152
** function object ('T_FUNCTION'). It returns the return value of <func>.
153
** 'CALL_0ARGS' is for calls passing no arguments, 'CALL_1ARGS' for calls
154
** passing one argument, and so on. 'CALL_XARGS' is for calls passing more
155
** than 5 arguments, where the arguments must be collected in a plain list,
156
** and this plain list must then be passed.
157
**
158
** 'CALL_<i>ARGS' can be used independently of whether the called function
159
** is a compiled or interpreted function. It checks that the number of
160
** passed arguments is the same as the number of arguments expected by the
161
** callee, or it collects the arguments in a list if the callee allows a
162
** variable number of arguments.
163
*/
164
#define CALL_0ARGS(f) HDLR_0ARGS(f)(f)
165
#define CALL_1ARGS(f,a1) HDLR_1ARGS(f)(f,a1)
166
#define CALL_2ARGS(f,a1,a2) HDLR_2ARGS(f)(f,a1,a2)
167
#define CALL_3ARGS(f,a1,a2,a3) HDLR_3ARGS(f)(f,a1,a2,a3)
168
#define CALL_4ARGS(f,a1,a2,a3,a4) HDLR_4ARGS(f)(f,a1,a2,a3,a4)
169
#define CALL_5ARGS(f,a1,a2,a3,a4,a5) HDLR_5ARGS(f)(f,a1,a2,a3,a4,a5)
170
#define CALL_6ARGS(f,a1,a2,a3,a4,a5,a6) HDLR_6ARGS(f)(f,a1,a2,a3,a4,a5,a6)
171
#define CALL_XARGS(f,as) HDLR_XARGS(f)(f,as)
172
173
174
/****************************************************************************
175
**
176
177
*F CALL_0ARGS_PROF( <func>, <arg1> ) . . . . . call a prof func with 0 args
178
*F CALL_1ARGS_PROF( <func>, <arg1>, ... ) . . call a prof func with 1 args
179
*F CALL_2ARGS_PROF( <func>, <arg1>, ... ) . . call a prof func with 2 args
180
*F CALL_3ARGS_PROF( <func>, <arg1>, ... ) . . call a prof func with 3 args
181
*F CALL_4ARGS_PROF( <func>, <arg1>, ... ) . . call a prof func with 4 args
182
*F CALL_5ARGS_PROF( <func>, <arg1>, ... ) . . call a prof func with 5 args
183
*F CALL_6ARGS_PROF( <func>, <arg1>, ... ) . . call a prof func with 6 args
184
*F CALL_XARGS_PROF( <func>, <arg1>, ... ) . . call a prof func with X args
185
**
186
** 'CALL_<i>ARGS_PROF' is used in the profile handler 'DoProf<i>args' to
187
** call the real handler stored in the profiling information of the
188
** function.
189
*/
190
#define CALL_0ARGS_PROF(f) \
191
HDLR_0ARGS(PROF_FUNC(f))(f)
192
193
#define CALL_1ARGS_PROF(f,a1) \
194
HDLR_1ARGS(PROF_FUNC(f))(f,a1)
195
196
#define CALL_2ARGS_PROF(f,a1,a2) \
197
HDLR_2ARGS(PROF_FUNC(f))(f,a1,a2)
198
199
#define CALL_3ARGS_PROF(f,a1,a2,a3) \
200
HDLR_3ARGS(PROF_FUNC(f))(f,a1,a2,a3)
201
202
#define CALL_4ARGS_PROF(f,a1,a2,a3,a4) \
203
HDLR_4ARGS(PROF_FUNC(f))(f,a1,a2,a3,a4)
204
205
#define CALL_5ARGS_PROF(f,a1,a2,a3,a4,a5) \
206
HDLR_5ARGS(PROF_FUNC(f))(f,a1,a2,a3,a4,a5)
207
208
#define CALL_6ARGS_PROF(f,a1,a2,a3,a4,a5,a6) \
209
HDLR_6ARGS(PROF_FUNC(f))(f,a1,a2,a3,a4,a5,a6)
210
211
#define CALL_XARGS_PROF(f,as) \
212
HDLR_XARGS(PROF_FUNC(f))(f,as)
213
214
215
/****************************************************************************
216
**
217
218
*F COUNT_PROF( <prof> ) . . . . . . . . number of invocations of a function
219
*F TIME_WITH_PROF( <prof> ) . . . . . . time with children in a function
220
*F TIME_WOUT_PROF( <prof> ) . . . . . . time without children in a function
221
*F STOR_WITH_PROF( <prof> ) . . . . storage with children in a function
222
*F STOR_WOUT_PROF( <prof> ) . . . . storage without children in a function
223
*V LEN_PROF . . . . . . . . . . . length of a profiling bag for a function
224
**
225
** With each function we associate two time measurements. First the *time
226
** spent by this function without its children*, i.e., the amount of time
227
** during which this function was active. Second the *time spent by this
228
** function with its children*, i.e., the amount of time during which this
229
** function was either active or suspended.
230
**
231
** Likewise with each function we associate the two storage measurements,
232
** the storage spent by this function without its children and the storage
233
** spent by this function with its children.
234
**
235
** These macros make it possible to access the various components of a
236
** profiling information bag <prof> for a function <func>.
237
**
238
** 'COUNT_PROF(<prof>)' is the number of calls to the function <func>.
239
** 'TIME_WITH_PROF(<prof>) is the time spent while the function <func> was
240
** either active or suspended. 'TIME_WOUT_PROF(<prof>)' is the time spent
241
** while the function <func> was active. 'STOR_WITH_PROF(<prof>)' is the
242
** amount of storage allocated while the function <func> was active or
243
** suspended. 'STOR_WOUT_PROF(<prof>)' is the amount of storage allocated
244
** while the function <func> was active. 'LEN_PROF' is the length of a
245
** profiling information bag.
246
*/
247
#define COUNT_PROF(prof) (INT_INTOBJ(ELM_PLIST(prof,1)))
248
#define TIME_WITH_PROF(prof) (INT_INTOBJ(ELM_PLIST(prof,2)))
249
#define TIME_WOUT_PROF(prof) (INT_INTOBJ(ELM_PLIST(prof,3)))
250
#define STOR_WITH_PROF(prof) (INT_INTOBJ(ELM_PLIST(prof,4)))
251
#define STOR_WOUT_PROF(prof) (INT_INTOBJ(ELM_PLIST(prof,5)))
252
253
#define SET_COUNT_PROF(prof,n) SET_ELM_PLIST(prof,1,INTOBJ_INT(n))
254
#define SET_TIME_WITH_PROF(prof,n) SET_ELM_PLIST(prof,2,INTOBJ_INT(n))
255
#define SET_TIME_WOUT_PROF(prof,n) SET_ELM_PLIST(prof,3,INTOBJ_INT(n))
256
#define SET_STOR_WITH_PROF(prof,n) SET_ELM_PLIST(prof,4,INTOBJ_INT(n))
257
#define SET_STOR_WOUT_PROF(prof,n) SET_ELM_PLIST(prof,5,INTOBJ_INT(n))
258
259
#define LEN_PROF 5
260
261
262
/****************************************************************************
263
**
264
265
*F FuncFILENAME_FUNC(Obj self, Obj func) . . . . . . . filename of function
266
*F FuncSTARTLINE_FUNC(Obj self, Obj func) . . . . . start line of function
267
*F FuncENDLINE_FUNC(Obj self, Obj func) . . . . . . . end line of function
268
**
269
** These functions, usually exported to GAP, get information about GAP
270
** functions */
271
Obj FuncFILENAME_FUNC(Obj self, Obj func);
272
Obj FuncSTARTLINE_FUNC(Obj self, Obj func);
273
Obj FuncENDLINE_FUNC(Obj self, Obj func);
274
275
/****************************************************************************
276
**
277
278
*F * * * * * * * * * * * * * create a new function * * * * * * * * * * * * *
279
*/
280
281
/****************************************************************************
282
**
283
284
*F InitHandlerFunc( <handler>, <cookie> ) . . . . . . . . register a handler
285
**
286
** Every handler should be registered (once) before it is installed in any
287
** function bag. This is needed so that it can be identified when loading a
288
** saved workspace. <cookie> should be a unique C string, identifying the
289
** handler
290
*/
291
292
extern void InitHandlerRegistration( void );
293
294
extern void InitHandlerFunc (
295
ObjFunc hdlr,
296
const Char * cookie );
297
298
extern const Char * CookieOfHandler(
299
ObjFunc hdlr );
300
301
extern ObjFunc HandlerOfCookie (
302
const Char * cookie );
303
304
extern void SortHandlers( UInt byWhat );
305
306
/****************************************************************************
307
**
308
*F NewFunction( <name>, <narg>, <nams>, <hdlr> ) . . . make a new function
309
*F NewFunctionC( <name>, <narg>, <nams>, <hdlr> ) . . . make a new function
310
*F NewFunctionT( <type>, <size>, <name>, <narg>, <nams>, <hdlr> )
311
*F NewFunctionCT( <type>, <size>, <name>, <narg>, <nams>, <hdlr> )
312
**
313
** 'NewFunction' creates and returns a new function. <name> must be a GAP
314
** string containing the name of the function. <narg> must be the number of
315
** arguments, where -1 means a variable number of arguments. <nams> must be
316
** a GAP list containg the names of the arguments. <hdlr> must be the
317
** C function (accepting <self> and the <narg> arguments) that will be
318
** called to execute the function.
319
**
320
** 'NewFunctionC' does the same as 'NewFunction', but expects <name> and
321
** <nams> as C strings.
322
**
323
** 'NewFunctionT' does the same as 'NewFunction', but allows to specify the
324
** <type> and <size> of the newly created bag.
325
**
326
** 'NewFunctionCT' does the same as 'NewFunction', but expects <name> and
327
** <nams> as C strings, and allows to specify the <type> and <size> of the
328
** newly created bag.
329
*/
330
extern Obj NewFunction (
331
Obj name,
332
Int narg,
333
Obj nams,
334
ObjFunc hdlr );
335
336
extern Obj NewFunctionC (
337
const Char * name,
338
Int narg,
339
const Char * nams,
340
ObjFunc hdlr );
341
342
extern Obj NewFunctionT (
343
UInt type,
344
UInt size,
345
Obj name,
346
Int narg,
347
Obj nams,
348
ObjFunc hdlr );
349
350
extern Obj NewFunctionCT (
351
UInt type,
352
UInt size,
353
const Char * name,
354
Int narg,
355
const Char * nams,
356
ObjFunc hdlr );
357
358
359
/****************************************************************************
360
**
361
*F ArgStringToList( <nams_c> )
362
**
363
** 'ArgStringToList' takes a C string <nams_c> containing a list of comma
364
** separated argument names, and turns it into a plist of strings, ready
365
** to be passed to 'NewFunction' as <nams>.
366
*/
367
extern Obj ArgStringToList(const Char *nams_c);
368
369
370
/****************************************************************************
371
**
372
373
*F * * * * * * * * * * * * * type and print function * * * * * * * * * * * *
374
*/
375
376
/****************************************************************************
377
**
378
379
*F PrintFunction( <func> ) . . . . . . . . . . . . . . . print a function
380
**
381
** 'PrintFunction' prints the function <func> in abbreviated form if
382
** 'PrintObjFull' is false.
383
*/
384
extern void PrintFunction (
385
Obj func );
386
387
388
/****************************************************************************
389
**
390
*F FuncCALL_FUNC_LIST( <self>, <func>, <list> ) . . . . . . call a function
391
**
392
** 'FuncCALL_FUNC_LIST' implements the internal function 'CallFuncList'.
393
**
394
** 'CallFuncList( <func>, <list> )'
395
**
396
** 'CallFuncList' calls the function <func> with the arguments list <list>,
397
** i.e., it is equivalent to '<func>( <list>[1], <list>[2]... )'.
398
*/
399
400
extern Obj CallFuncList(
401
Obj func,
402
Obj list);
403
404
extern Obj CallFuncListOper;
405
406
/****************************************************************************
407
**
408
409
*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
410
*/
411
412
/****************************************************************************
413
**
414
415
*F InitInfoCalls() . . . . . . . . . . . . . . . . . table of init functions
416
*/
417
StructInitInfo * InitInfoCalls ( void );
418
419
420
#endif // GAP_CALLS_H
421
422
/****************************************************************************
423
**
424
425
*E calls.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
426
*/
427
428