Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
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
Project: cocalc-sagemath-dev-slelievre
Views: 418346/****************************************************************************1**2*W calls.c GAP source Martin Schönert3**4**5*Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany6*Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland7*Y Copyright (C) 2002 The GAP Group8**9** This file contains the functions for the function call mechanism package.10**11** For a description of what the function call mechanism is about see the12** declaration part of this package.13**14** Each function is represented by a function bag (of type 'T_FUNCTION'),15** which has the following format.16**17** +-------+-------+- - - -+-------+18** |handler|handler| |handler| (for all functions)19** | 0 | 1 | | 7 |20** +-------+-------+- - - -+-------+21**22** +-------+-------+-------+-------+23** | name | number| args &| prof- | (for all functions)24** | func. | args | locals| iling |25** +-------+-------+-------+-------+26**27** +-------+-------+-------+-------+28** | number| body | envir-| funcs.| (only for interpreted functions)29** | locals| func. | onment| exprs.|30** +-------+-------+-------+-------+31**32** ...what the handlers are..33** ...what the other components are...34*/35#include "system.h" /* system dependent part */36373839#include "gasman.h" /* garbage collector */40#include "objects.h" /* objects */41#include "scanner.h" /* scanner */4243#include "gap.h" /* error handling, initialisation */4445#include "gvars.h" /* global variables */4647#include "calls.h" /* generic call mechanism */4849#include "opers.h" /* generic operations */5051#include "records.h" /* generic records */52#include "precord.h" /* plain records */5354#include "lists.h" /* generic lists */5556#include "bool.h" /* booleans */5758#include "plist.h" /* plain lists */59#include "string.h" /* strings */6061#include "code.h" /* coder */6263#include "stats.h" /* statements */6465#include "saveload.h" /* saving and loading */66#include "tls.h" /* thread-local storage */6768#include "vars.h" /* variables */6970#include <assert.h>7172/****************************************************************************73**7475*F * * * * wrapper for functions with variable number of arguments * * * * *76*/7778/****************************************************************************79**8081*F DoWrap0args( <self> ) . . . . . . . . . . . wrap up 0 arguments in a list82**83** 'DoWrap<i>args' accepts the <i> arguments <arg1>, <arg2>, and so on,84** wraps them up in a list, and then calls <self> again via 'CALL_XARGS',85** passing this list. 'DoWrap<i>args' are the handlers for callees that86** accept a variable number of arguments. Note that there is no87** 'DoWrapXargs' handler, since in this case the function call mechanism88** already requires that the passed arguments are collected in a list.89*/90Obj DoWrap0args (91Obj self )92{93Obj result; /* value of function call, result */94Obj args; /* arguments list */9596/* make the arguments list */97args = NEW_PLIST( T_PLIST, 0 );98SET_LEN_PLIST( args, 0 );99100/* call the variable number of arguments function */101result = CALL_XARGS( self, args );102return result;103}104105106/****************************************************************************107**108*F DoWrap1args( <self>, <arg1> ) . . . . . . . wrap up 1 arguments in a list109*/110Obj DoWrap1args (111Obj self,112Obj arg1 )113{114Obj result; /* value of function call, result */115Obj args; /* arguments list */116117/* make the arguments list */118args = NEW_PLIST( T_PLIST, 1 );119SET_LEN_PLIST( args, 1 );120SET_ELM_PLIST( args, 1, arg1 );121122/* call the variable number of arguments function */123result = CALL_XARGS( self, args );124return result;125}126127128/****************************************************************************129**130*F DoWrap2args( <self>, <arg1>, ... ) . . . . wrap up 2 arguments in a list131*/132Obj DoWrap2args (133Obj self,134Obj arg1,135Obj arg2 )136{137Obj result; /* value of function call, result */138Obj args; /* arguments list */139140/* make the arguments list */141args = NEW_PLIST( T_PLIST, 2 );142SET_LEN_PLIST( args, 2 );143SET_ELM_PLIST( args, 1, arg1 );144SET_ELM_PLIST( args, 2, arg2 );145146/* call the variable number of arguments function */147result = CALL_XARGS( self, args );148return result;149}150151152/****************************************************************************153**154*F DoWrap3args( <self>, <arg1>, ... ) . . . . wrap up 3 arguments in a list155*/156Obj DoWrap3args (157Obj self,158Obj arg1,159Obj arg2,160Obj arg3 )161{162Obj result; /* value of function call, result */163Obj args; /* arguments list */164165/* make the arguments list */166args = NEW_PLIST( T_PLIST, 3 );167SET_LEN_PLIST( args, 3 );168SET_ELM_PLIST( args, 1, arg1 );169SET_ELM_PLIST( args, 2, arg2 );170SET_ELM_PLIST( args, 3, arg3 );171172/* call the variable number of arguments function */173result = CALL_XARGS( self, args );174return result;175}176177178/****************************************************************************179**180*F DoWrap4args( <self>, <arg1>, ... ) . . . . wrap up 4 arguments in a list181*/182Obj DoWrap4args (183Obj self,184Obj arg1,185Obj arg2,186Obj arg3,187Obj arg4 )188{189Obj result; /* value of function call, result */190Obj args; /* arguments list */191192/* make the arguments list */193args = NEW_PLIST( T_PLIST, 4 );194SET_LEN_PLIST( args, 4 );195SET_ELM_PLIST( args, 1, arg1 );196SET_ELM_PLIST( args, 2, arg2 );197SET_ELM_PLIST( args, 3, arg3 );198SET_ELM_PLIST( args, 4, arg4 );199200/* call the variable number of arguments function */201result = CALL_XARGS( self, args );202return result;203}204205206/****************************************************************************207**208*F DoWrap5args( <self>, <arg1>, ... ) . . . . wrap up 5 arguments in a list209*/210Obj DoWrap5args (211Obj self,212Obj arg1,213Obj arg2,214Obj arg3,215Obj arg4,216Obj arg5 )217{218Obj result; /* value of function call, result */219Obj args; /* arguments list */220221/* make the arguments list */222args = NEW_PLIST( T_PLIST, 5 );223SET_LEN_PLIST( args, 5 );224SET_ELM_PLIST( args, 1, arg1 );225SET_ELM_PLIST( args, 2, arg2 );226SET_ELM_PLIST( args, 3, arg3 );227SET_ELM_PLIST( args, 4, arg4 );228SET_ELM_PLIST( args, 5, arg5 );229230/* call the variable number of arguments function */231result = CALL_XARGS( self, args );232return result;233}234235236/****************************************************************************237**238*F DoWrap6args( <self>, <arg1>, ... ) . . . . wrap up 6 arguments in a list239*/240Obj DoWrap6args (241Obj self,242Obj arg1,243Obj arg2,244Obj arg3,245Obj arg4,246Obj arg5,247Obj arg6 )248{249Obj result; /* value of function call, result */250Obj args; /* arguments list */251252/* make the arguments list */253args = NEW_PLIST( T_PLIST, 6 );254SET_LEN_PLIST( args, 6 );255SET_ELM_PLIST( args, 1, arg1 );256SET_ELM_PLIST( args, 2, arg2 );257SET_ELM_PLIST( args, 3, arg3 );258SET_ELM_PLIST( args, 4, arg4 );259SET_ELM_PLIST( args, 5, arg5 );260SET_ELM_PLIST( args, 6, arg6 );261262/* call the variable number of arguments function */263result = CALL_XARGS( self, args );264return result;265}266267268/****************************************************************************269**270271*F * * wrapper for functions with do not support the number of arguments * *272*/273274/****************************************************************************275**276277*F DoFail0args( <self> ) . . . . . . fail a function call with 0 arguments278**279** 'DoFail<i>args' accepts the <i> arguments <arg1>, <arg2>, and so on, and280** signals an error, because the function for which they are installed281** expects another number of arguments. 'DoFail<i>args' are the handlers in282** the other slots of a function.283*/284285/* Pull this out to avoid repetition, since it gets a little more complex in286the presence of partially variadic functions */287288Obj NargError( Obj func, Int actual) {289Int narg = NARG_FUNC(func);290291if (narg >= 0) {292assert(narg != actual);293return ErrorReturnObj(294"Function: number of arguments must be %d (not %d)",295narg, actual,296"you can replace the argument list <args> via 'return <args>;'" );297} else {298assert(-narg-1 > actual);299return ErrorReturnObj(300"Function: number of arguments must be at least %d (not %d)",301-narg-1, actual,302"you can replace the argument list <args> via 'return <args>;'" );303}304}305306Obj DoFail0args (307Obj self )308{309Obj argx; /* arguments list (to continue) */310argx =NargError(self, 0);311return CallFuncList( self, argx );312}313314315/****************************************************************************316**317*F DoFail1args( <self>,<arg1> ) . . . fail a function call with 1 arguments318*/319Obj DoFail1args (320Obj self,321Obj arg1 )322{323Obj argx; /* arguments list (to continue) */324argx =NargError(self, 1);325return CallFuncList( self, argx );326}327328329/****************************************************************************330**331*F DoFail2args( <self>, <arg1>, ... ) fail a function call with 2 arguments332*/333Obj DoFail2args (334Obj self,335Obj arg1,336Obj arg2 )337{338Obj argx; /* arguments list (to continue) */339argx =NargError(self, 2);340return CallFuncList( self, argx );341}342343344/****************************************************************************345**346*F DoFail3args( <self>, <arg1>, ... ) fail a function call with 3 arguments347*/348Obj DoFail3args (349Obj self,350Obj arg1,351Obj arg2,352Obj arg3 )353{354Obj argx; /* arguments list (to continue) */355argx =NargError(self, 3);356return CallFuncList( self, argx );357}358359360/****************************************************************************361**362*F DoFail4args( <self>, <arg1>, ... ) fail a function call with 4 arguments363*/364Obj DoFail4args (365Obj self,366Obj arg1,367Obj arg2,368Obj arg3,369Obj arg4 )370{371Obj argx; /* arguments list (to continue) */372argx =NargError(self, 4);373return CallFuncList( self, argx );374}375376377/****************************************************************************378**379*F DoFail5args( <self>, <arg1>, ... ) fail a function call with 5 arguments380*/381Obj DoFail5args (382Obj self,383Obj arg1,384Obj arg2,385Obj arg3,386Obj arg4,387Obj arg5 )388{389Obj argx; /* arguments list (to continue) */390argx =NargError(self, 5);391return CallFuncList( self, argx );392}393394395/****************************************************************************396**397*F DoFail6args( <self>, <arg1>, ... ) fail a function call with 6 arguments398*/399Obj DoFail6args (400Obj self,401Obj arg1,402Obj arg2,403Obj arg3,404Obj arg4,405Obj arg5,406Obj arg6 )407{408Obj argx; /* arguments list (to continue) */409argx =NargError(self, 6);410return CallFuncList( self, argx );411}412413414/****************************************************************************415**416*F DoFailXargs( <self>, <args> ) . . fail a function call with X arguments417*/418Obj DoFailXargs (419Obj self,420Obj args )421{422Obj argx; /* arguments list (to continue) */423argx =NargError(self, LEN_LIST(args));424return CallFuncList( self, argx );425}426427428/****************************************************************************429**430431*F * * * * * * * * * * * * * wrapper for profiling * * * * * * * * * * * * *432*/433434/****************************************************************************435**436437*V TimeDone . . . . . . amount of time spent for completed function calls438**439** 'TimeDone' is the amount of time spent for all function calls that have440** already been completed.441*/442UInt TimeDone;443444445/****************************************************************************446**447*V StorDone . . . . . amount of storage spent for completed function calls448**449** 'StorDone' is the amount of storage spent for all function call that have450** already been completed.451*/452UInt StorDone;453454455/****************************************************************************456**457*F DoProf0args( <self> ) . . . . . . . . profile a function with 0 arguments458**459** 'DoProf<i>args' accepts the <i> arguments <arg1>, <arg2>, and so on, and460** calls the function through the secondary handler. It also updates the461** profiling information in the profiling information bag of the called462** function. 'DoProf<i>args' are the primary handlers for all functions463** when profiling is requested.464*/465Obj DoProf0args (466Obj self )467{468Obj result; /* value of function call, result */469Obj prof; /* profiling bag */470UInt timeElse; /* time spent elsewhere */471UInt timeCurr; /* time spent in current funcs. */472UInt storElse; /* storage spent elsewhere */473UInt storCurr; /* storage spent in current funcs. */474475/* get the profiling bag */476prof = PROF_FUNC( PROF_FUNC( self ) );477478/* time and storage spent so far while this function what not active */479timeElse = SyTime() - TIME_WITH_PROF(prof);480storElse = SizeAllBags - STOR_WITH_PROF(prof);481482/* time and storage spent so far by all currently suspended functions */483timeCurr = SyTime() - TimeDone;484storCurr = SizeAllBags - StorDone;485486/* call the real function */487result = CALL_0ARGS_PROF( self );488489/* number of invocation of this function */490SET_COUNT_PROF( prof, COUNT_PROF(prof) + 1 );491492/* time and storage spent in this function and its children */493SET_TIME_WITH_PROF( prof, SyTime() - timeElse );494SET_STOR_WITH_PROF( prof, SizeAllBags - storElse );495496/* time and storage spent by this invocation of this function */497timeCurr = SyTime() - TimeDone - timeCurr;498SET_TIME_WOUT_PROF( prof, TIME_WOUT_PROF(prof) + timeCurr );499TimeDone += timeCurr;500storCurr = SizeAllBags - StorDone - storCurr;501SET_STOR_WOUT_PROF( prof, STOR_WOUT_PROF(prof) + storCurr );502StorDone += storCurr;503504/* return the result from the function */505return result;506}507508509/****************************************************************************510**511*F DoProf1args( <self>, <arg1>) . . . . profile a function with 1 arguments512*/513Obj DoProf1args (514Obj self,515Obj arg1 )516{517Obj result; /* value of function call, result */518Obj prof; /* profiling bag */519UInt timeElse; /* time spent elsewhere */520UInt timeCurr; /* time spent in current funcs. */521UInt storElse; /* storage spent elsewhere */522UInt storCurr; /* storage spent in current funcs. */523524/* get the profiling bag */525prof = PROF_FUNC( PROF_FUNC( self ) );526527/* time and storage spent so far while this function what not active */528timeElse = SyTime() - TIME_WITH_PROF(prof);529storElse = SizeAllBags - STOR_WITH_PROF(prof);530531/* time and storage spent so far by all currently suspended functions */532timeCurr = SyTime() - TimeDone;533storCurr = SizeAllBags - StorDone;534535/* call the real function */536result = CALL_1ARGS_PROF( self, arg1 );537538/* number of invocation of this function */539SET_COUNT_PROF( prof, COUNT_PROF(prof) + 1 );540541/* time and storage spent in this function and its children */542SET_TIME_WITH_PROF( prof, SyTime() - timeElse );543SET_STOR_WITH_PROF( prof, SizeAllBags - storElse );544545/* time and storage spent by this invocation of this function */546timeCurr = SyTime() - TimeDone - timeCurr;547SET_TIME_WOUT_PROF( prof, TIME_WOUT_PROF(prof) + timeCurr );548TimeDone += timeCurr;549storCurr = SizeAllBags - StorDone - storCurr;550SET_STOR_WOUT_PROF( prof, STOR_WOUT_PROF(prof) + storCurr );551StorDone += storCurr;552553/* return the result from the function */554return result;555}556557558/****************************************************************************559**560*F DoProf2args( <self>, <arg1>, ... ) . profile a function with 2 arguments561*/562Obj DoProf2args (563Obj self,564Obj arg1,565Obj arg2 )566{567Obj result; /* value of function call, result */568Obj prof; /* profiling bag */569UInt timeElse; /* time spent elsewhere */570UInt timeCurr; /* time spent in current funcs. */571UInt storElse; /* storage spent elsewhere */572UInt storCurr; /* storage spent in current funcs. */573574/* get the profiling bag */575prof = PROF_FUNC( PROF_FUNC( self ) );576577/* time and storage spent so far while this function what not active */578timeElse = SyTime() - TIME_WITH_PROF(prof);579storElse = SizeAllBags - STOR_WITH_PROF(prof);580581/* time and storage spent so far by all currently suspended functions */582timeCurr = SyTime() - TimeDone;583storCurr = SizeAllBags - StorDone;584585/* call the real function */586result = CALL_2ARGS_PROF( self, arg1, arg2 );587588/* number of invocation of this function */589SET_COUNT_PROF( prof, COUNT_PROF(prof) + 1 );590591/* time and storage spent in this function and its children */592SET_TIME_WITH_PROF( prof, SyTime() - timeElse );593SET_STOR_WITH_PROF( prof, SizeAllBags - storElse );594595/* time and storage spent by this invocation of this function */596timeCurr = SyTime() - TimeDone - timeCurr;597SET_TIME_WOUT_PROF( prof, TIME_WOUT_PROF(prof) + timeCurr );598TimeDone += timeCurr;599storCurr = SizeAllBags - StorDone - storCurr;600SET_STOR_WOUT_PROF( prof, STOR_WOUT_PROF(prof) + storCurr );601StorDone += storCurr;602603/* return the result from the function */604return result;605}606607608/****************************************************************************609**610*F DoProf3args( <self>, <arg1>, ... ) . profile a function with 3 arguments611*/612Obj DoProf3args (613Obj self,614Obj arg1,615Obj arg2,616Obj arg3 )617{618Obj result; /* value of function call, result */619Obj prof; /* profiling bag */620UInt timeElse; /* time spent elsewhere */621UInt timeCurr; /* time spent in current funcs. */622UInt storElse; /* storage spent elsewhere */623UInt storCurr; /* storage spent in current funcs. */624625/* get the profiling bag */626prof = PROF_FUNC( PROF_FUNC( self ) );627628/* time and storage spent so far while this function what not active */629timeElse = SyTime() - TIME_WITH_PROF(prof);630storElse = SizeAllBags - STOR_WITH_PROF(prof);631632/* time and storage spent so far by all currently suspended functions */633timeCurr = SyTime() - TimeDone;634storCurr = SizeAllBags - StorDone;635636/* call the real function */637result = CALL_3ARGS_PROF( self, arg1, arg2, arg3 );638639/* number of invocation of this function */640SET_COUNT_PROF( prof, COUNT_PROF(prof) + 1 );641642/* time and storage spent in this function and its children */643SET_TIME_WITH_PROF( prof, SyTime() - timeElse );644SET_STOR_WITH_PROF( prof, SizeAllBags - storElse );645646/* time and storage spent by this invocation of this function */647timeCurr = SyTime() - TimeDone - timeCurr;648SET_TIME_WOUT_PROF( prof, TIME_WOUT_PROF(prof) + timeCurr );649TimeDone += timeCurr;650storCurr = SizeAllBags - StorDone - storCurr;651SET_STOR_WOUT_PROF( prof, STOR_WOUT_PROF(prof) + storCurr );652StorDone += storCurr;653654/* return the result from the function */655return result;656}657658659/****************************************************************************660**661*F DoProf4args( <self>, <arg1>, ... ) . profile a function with 4 arguments662*/663Obj DoProf4args (664Obj self,665Obj arg1,666Obj arg2,667Obj arg3,668Obj arg4 )669{670Obj result; /* value of function call, result */671Obj prof; /* profiling bag */672UInt timeElse; /* time spent elsewhere */673UInt timeCurr; /* time spent in current funcs. */674UInt storElse; /* storage spent elsewhere */675UInt storCurr; /* storage spent in current funcs. */676677/* get the profiling bag */678prof = PROF_FUNC( PROF_FUNC( self ) );679680/* time and storage spent so far while this function what not active */681timeElse = SyTime() - TIME_WITH_PROF(prof);682storElse = SizeAllBags - STOR_WITH_PROF(prof);683684/* time and storage spent so far by all currently suspended functions */685timeCurr = SyTime() - TimeDone;686storCurr = SizeAllBags - StorDone;687688/* call the real function */689result = CALL_4ARGS_PROF( self, arg1, arg2, arg3, arg4 );690691/* number of invocation of this function */692SET_COUNT_PROF( prof, COUNT_PROF(prof) + 1 );693694/* time and storage spent in this function and its children */695SET_TIME_WITH_PROF( prof, SyTime() - timeElse );696SET_STOR_WITH_PROF( prof, SizeAllBags - storElse );697698/* time and storage spent by this invocation of this function */699timeCurr = SyTime() - TimeDone - timeCurr;700SET_TIME_WOUT_PROF( prof, TIME_WOUT_PROF(prof) + timeCurr );701TimeDone += timeCurr;702storCurr = SizeAllBags - StorDone - storCurr;703SET_STOR_WOUT_PROF( prof, STOR_WOUT_PROF(prof) + storCurr );704StorDone += storCurr;705706/* return the result from the function */707return result;708}709710711/****************************************************************************712**713*F DoProf5args( <self>, <arg1>, ... ) . profile a function with 5 arguments714*/715Obj DoProf5args (716Obj self,717Obj arg1,718Obj arg2,719Obj arg3,720Obj arg4,721Obj arg5 )722{723Obj result; /* value of function call, result */724Obj prof; /* profiling bag */725UInt timeElse; /* time spent elsewhere */726UInt timeCurr; /* time spent in current funcs. */727UInt storElse; /* storage spent elsewhere */728UInt storCurr; /* storage spent in current funcs. */729730/* get the profiling bag */731prof = PROF_FUNC( PROF_FUNC( self ) );732733/* time and storage spent so far while this function what not active */734timeElse = SyTime() - TIME_WITH_PROF(prof);735storElse = SizeAllBags - STOR_WITH_PROF(prof);736737/* time and storage spent so far by all currently suspended functions */738timeCurr = SyTime() - TimeDone;739storCurr = SizeAllBags - StorDone;740741/* call the real function */742result = CALL_5ARGS_PROF( self, arg1, arg2, arg3, arg4, arg5 );743744/* number of invocation of this function */745SET_COUNT_PROF( prof, COUNT_PROF(prof) + 1 );746747/* time and storage spent in this function and its children */748SET_TIME_WITH_PROF( prof, SyTime() - timeElse );749SET_STOR_WITH_PROF( prof, SizeAllBags - storElse );750751/* time and storage spent by this invocation of this function */752timeCurr = SyTime() - TimeDone - timeCurr;753SET_TIME_WOUT_PROF( prof, TIME_WOUT_PROF(prof) + timeCurr );754TimeDone += timeCurr;755storCurr = SizeAllBags - StorDone - storCurr;756SET_STOR_WOUT_PROF( prof, STOR_WOUT_PROF(prof) + storCurr );757StorDone += storCurr;758759/* return the result from the function */760return result;761}762763764/****************************************************************************765**766*F DoProf6args( <self>, <arg1>, ... ) . profile a function with 6 arguments767*/768Obj DoProf6args (769Obj self,770Obj arg1,771Obj arg2,772Obj arg3,773Obj arg4,774Obj arg5,775Obj arg6 )776{777Obj result; /* value of function call, result */778Obj prof; /* profiling bag */779UInt timeElse; /* time spent elsewhere */780UInt timeCurr; /* time spent in current funcs. */781UInt storElse; /* storage spent elsewhere */782UInt storCurr; /* storage spent in current funcs. */783784/* get the profiling bag */785prof = PROF_FUNC( PROF_FUNC( self ) );786787/* time and storage spent so far while this function what not active */788timeElse = SyTime() - TIME_WITH_PROF(prof);789storElse = SizeAllBags - STOR_WITH_PROF(prof);790791/* time and storage spent so far by all currently suspended functions */792timeCurr = SyTime() - TimeDone;793storCurr = SizeAllBags - StorDone;794795/* call the real function */796result = CALL_6ARGS_PROF( self, arg1, arg2, arg3, arg4, arg5, arg6 );797798/* number of invocation of this function */799SET_COUNT_PROF( prof, COUNT_PROF(prof) + 1 );800801/* time and storage spent in this function and its children */802SET_TIME_WITH_PROF( prof, SyTime() - timeElse );803SET_STOR_WITH_PROF( prof, SizeAllBags - storElse );804805/* time and storage spent by this invocation of this function */806timeCurr = SyTime() - TimeDone - timeCurr;807SET_TIME_WOUT_PROF( prof, TIME_WOUT_PROF(prof) + timeCurr );808TimeDone += timeCurr;809storCurr = SizeAllBags - StorDone - storCurr;810SET_STOR_WOUT_PROF( prof, STOR_WOUT_PROF(prof) + storCurr );811StorDone += storCurr;812813/* return the result from the function */814return result;815}816817818/****************************************************************************819**820*F DoProfXargs( <self>, <args> ) . . . . profile a function with X arguments821*/822Obj DoProfXargs (823Obj self,824Obj args )825{826Obj result; /* value of function call, result */827Obj prof; /* profiling bag */828UInt timeElse; /* time spent elsewhere */829UInt timeCurr; /* time spent in current funcs. */830UInt storElse; /* storage spent elsewhere */831UInt storCurr; /* storage spent in current funcs. */832833/* get the profiling bag */834prof = PROF_FUNC( PROF_FUNC( self ) );835836/* time and storage spent so far while this function what not active */837timeElse = SyTime() - TIME_WITH_PROF(prof);838storElse = SizeAllBags - STOR_WITH_PROF(prof);839840/* time and storage spent so far by all currently suspended functions */841timeCurr = SyTime() - TimeDone;842storCurr = SizeAllBags - StorDone;843844/* call the real function */845result = CALL_XARGS_PROF( self, args );846847/* number of invocation of this function */848SET_COUNT_PROF( prof, COUNT_PROF(prof) + 1 );849850/* time and storage spent in this function and its children */851SET_TIME_WITH_PROF( prof, SyTime() - timeElse );852SET_STOR_WITH_PROF( prof, SizeAllBags - storElse );853854/* time and storage spent by this invocation of this function */855timeCurr = SyTime() - TimeDone - timeCurr;856SET_TIME_WOUT_PROF( prof, TIME_WOUT_PROF(prof) + timeCurr );857TimeDone += timeCurr;858storCurr = SizeAllBags - StorDone - storCurr;859SET_STOR_WOUT_PROF( prof, STOR_WOUT_PROF(prof) + storCurr );860StorDone += storCurr;861862/* return the result from the function */863return result;864}865866867/****************************************************************************868**869870*F * * * * * * * * * * * * * create a new function * * * * * * * * * * * * *871*/872873/****************************************************************************874**875876*F InitHandlerFunc( <handler>, <cookie> ) . . . . . . . . register a handler877**878** Every handler should be registered (once) before it is installed in any879** function bag. This is needed so that it can be identified when loading a880** saved workspace. <cookie> should be a unique C string, identifying the881** handler882*/883#ifndef MAX_HANDLERS884#define MAX_HANDLERS 20000885#endif886887typedef struct {888ObjFunc hdlr;889const Char * cookie;890}891TypeHandlerInfo;892893static UInt HandlerSortingStatus;894895static TypeHandlerInfo HandlerFuncs[MAX_HANDLERS];896static UInt NHandlerFuncs;897898void InitHandlerFunc (899ObjFunc hdlr,900const Char * cookie )901{902if ( NHandlerFuncs >= MAX_HANDLERS ) {903Pr( "No room left for function handler\n", 0L, 0L );904SyExit(1);905}906#ifdef DEBUG_HANDLER_REGISTRATION907{908UInt i;909for (i = 0; i < NHandlerFuncs; i++)910if (!strcmp(HandlerFuncs[i].cookie, cookie))911Pr("Duplicate cookie %s\n", (Int)cookie, 0L);912}913#endif914HandlerFuncs[NHandlerFuncs].hdlr = hdlr;915HandlerFuncs[NHandlerFuncs].cookie = cookie;916HandlerSortingStatus = 0; /* no longer sorted by handler or cookie */917NHandlerFuncs++;918}919920921922/****************************************************************************923**924*f CheckHandlersBag( <bag> ) . . . . . . check that handlers are initialised925*/926927void InitHandlerRegistration( void )928{929/* initialize these here rather than statically to allow for restart */930/* can't do them in InitKernel of this module because it's called too late931so make it a function and call it from an earlier InitKernel */932HandlerSortingStatus = 0;933NHandlerFuncs = 0;934935}936937static void CheckHandlersBag(938Bag bag )939{940#ifdef DEBUG_HANDLER_REGISTRATION941UInt i;942UInt j;943ObjFunc hdlr;944945if ( TNUM_BAG(bag) == T_FUNCTION ) {946for ( j = 0; j < 8; j++ ) {947hdlr = HDLR_FUNC(bag,j);948949/* zero handlers are used in a few odd places */950if ( hdlr != 0 ) {951for ( i = 0; i < NHandlerFuncs; i++ ) {952if ( hdlr == HandlerFuncs[i].hdlr )953break;954}955if ( i == NHandlerFuncs ) {956Pr("Unregistered Handler %d args ", j, 0L);957PrintObj(NAME_FUNC(bag));958Pr("\n",0L,0L);959}960}961}962}963#endif964return;965}966967void CheckAllHandlers(968void )969{970CallbackForAllBags( CheckHandlersBag);971return;972}973974975static int IsLessHandlerInfo (976TypeHandlerInfo * h1,977TypeHandlerInfo * h2,978UInt byWhat )979{980switch (byWhat) {981case 1:982/* cast to please Irix CC and HPUX CC */983return (UInt)(h1->hdlr) < (UInt)(h2->hdlr);984case 2:985return strcmp(h1->cookie, h2->cookie) < 0;986default:987ErrorQuit( "Invalid sort mode %u", (Int)byWhat, 0L );988return 0; /* please lint */989}990}991992void SortHandlers( UInt byWhat )993{994TypeHandlerInfo tmp;995UInt len, h, i, k;996if (HandlerSortingStatus == byWhat)997return;998len = NHandlerFuncs;999h = 1;1000while ( 9*h + 4 < len )1001{ h = 3*h + 1; }1002while ( 0 < h ) {1003for ( i = h; i < len; i++ ) {1004tmp = HandlerFuncs[i];1005k = i;1006while ( h <= k && IsLessHandlerInfo(&tmp, HandlerFuncs+(k-h), byWhat))1007{1008HandlerFuncs[k] = HandlerFuncs[k-h];1009k -= h;1010}1011HandlerFuncs[k] = tmp;1012}1013h = h / 3;1014}1015HandlerSortingStatus = byWhat;1016return;1017}10181019const Char * CookieOfHandler (1020ObjFunc hdlr )1021{1022UInt i, top, bottom, middle;10231024if ( HandlerSortingStatus != 1 ) {1025for ( i = 0; i < NHandlerFuncs; i++ ) {1026if ( hdlr == HandlerFuncs[i].hdlr )1027return HandlerFuncs[i].cookie;1028}1029return (Char *)0L;1030}1031else {1032top = NHandlerFuncs;1033bottom = 0;1034while ( top >= bottom ) {1035middle = (top + bottom)/2;1036if ( (UInt)(hdlr) < (UInt)(HandlerFuncs[middle].hdlr) )1037top = middle-1;1038else if ( (UInt)(hdlr) > (UInt)(HandlerFuncs[middle].hdlr) )1039bottom = middle+1;1040else1041return HandlerFuncs[middle].cookie;1042}1043return (Char *)0L;1044}1045}10461047ObjFunc HandlerOfCookie(1048const Char * cookie )1049{1050Int i,top,bottom,middle;1051Int res;1052if (HandlerSortingStatus != 2)1053{1054for (i = 0; i < NHandlerFuncs; i++)1055{1056if (strcmp(cookie, HandlerFuncs[i].cookie) == 0)1057return HandlerFuncs[i].hdlr;1058}1059return (ObjFunc)0L;1060}1061else1062{1063top = NHandlerFuncs;1064bottom = 0;1065while (top >= bottom) {1066middle = (top + bottom)/2;1067res = strcmp(cookie,HandlerFuncs[middle].cookie);1068if (res < 0)1069top = middle-1;1070else if (res > 0)1071bottom = middle+1;1072else1073return HandlerFuncs[middle].hdlr;1074}1075return (ObjFunc)0L;1076}1077}1078107910801081/****************************************************************************1082**10831084*F NewFunction( <name>, <narg>, <nams>, <hdlr> ) . . . . make a new function1085**1086** 'NewFunction' creates and returns a new function. <name> must be a GAP1087** string containing the name of the function. <narg> must be the number of1088** arguments, where -1 means a variable number of arguments. <nams> must be1089** a GAP list containg the names of the arguments. <hdlr> must be the1090** C function (accepting <self> and the <narg> arguments) that will be1091** called to execute the function.1092*/1093Obj NewFunction (1094Obj name,1095Int narg,1096Obj nams,1097ObjFunc hdlr )1098{1099return NewFunctionT( T_FUNCTION, SIZE_FUNC, name, narg, nams, hdlr );1100}110111021103/****************************************************************************1104**1105*F NewFunctionC( <name>, <narg>, <nams>, <hdlr> ) . . . make a new function1106**1107** 'NewFunctionC' does the same as 'NewFunction', but expects <name> and1108** <nams> as C strings.1109*/1110Obj NewFunctionC (1111const Char * name,1112Int narg,1113const Char * nams,1114ObjFunc hdlr )1115{1116return NewFunctionCT( T_FUNCTION, SIZE_FUNC, name, narg, nams, hdlr );1117}111811191120/****************************************************************************1121**1122*F NewFunctionT( <type>, <size>, <name>, <narg>, <nams>, <hdlr> )1123**1124** 'NewFunctionT' does the same as 'NewFunction', but allows to specify the1125** <type> and <size> of the newly created bag.1126*/1127Obj NewFunctionT (1128UInt type,1129UInt size,1130Obj name,1131Int narg,1132Obj nams,1133ObjFunc hdlr )1134{1135Obj func; /* function, result */1136Obj prof; /* profiling bag */113711381139/* make the function object */1140func = NewBag( type, size );11411142/* create a function with a fixed number of arguments */1143if ( narg >= 0 ) {1144HDLR_FUNC(func,0) = DoFail0args;1145HDLR_FUNC(func,1) = DoFail1args;1146HDLR_FUNC(func,2) = DoFail2args;1147HDLR_FUNC(func,3) = DoFail3args;1148HDLR_FUNC(func,4) = DoFail4args;1149HDLR_FUNC(func,5) = DoFail5args;1150HDLR_FUNC(func,6) = DoFail6args;1151HDLR_FUNC(func,7) = DoFailXargs;1152HDLR_FUNC( func, (narg <= 6 ? narg : 7) ) = hdlr;1153}11541155/* create a function with a variable number of arguments */1156else {1157HDLR_FUNC(func,0) = (narg >= -1) ? DoWrap0args : DoFail0args;1158HDLR_FUNC(func,1) = (narg >= -2) ? DoWrap1args : DoFail1args;1159HDLR_FUNC(func,2) = (narg >= -3) ? DoWrap2args : DoFail2args;1160HDLR_FUNC(func,3) = (narg >= -4) ? DoWrap3args : DoFail3args;1161HDLR_FUNC(func,4) = (narg >= -5) ? DoWrap4args : DoFail4args;1162HDLR_FUNC(func,5) = (narg >= -6) ? DoWrap5args : DoFail5args;1163HDLR_FUNC(func,6) = (narg >= -7) ? DoWrap6args : DoFail6args;1164HDLR_FUNC(func,7) = hdlr;1165}11661167/* enter the arguments and the names */1168NAME_FUNC(func) = name;1169NARG_FUNC(func) = narg;1170NAMS_FUNC(func) = nams;1171if (nams) MakeBagPublic(nams);1172CHANGED_BAG(func);11731174/* enter the profiling bag */1175prof = NEW_PLIST( T_PLIST, LEN_PROF );1176SET_LEN_PLIST( prof, LEN_PROF );1177SET_COUNT_PROF( prof, 0 );1178SET_TIME_WITH_PROF( prof, 0 );1179SET_TIME_WOUT_PROF( prof, 0 );1180SET_STOR_WITH_PROF( prof, 0 );1181SET_STOR_WOUT_PROF( prof, 0 );1182PROF_FUNC(func) = prof;1183CHANGED_BAG(func);11841185/* return the function bag */1186return func;1187}118811891190/****************************************************************************1191**1192*F NewFunctionCT( <type>, <size>, <name>, <narg>, <nams>, <hdlr> )1193**1194** 'NewFunctionCT' does the same as 'NewFunction', but expects <name> and1195** <nams> as C strings, and allows to specify the <type> and <size> of the1196** newly created bag.1197*/1198Obj NewFunctionCT (1199UInt type,1200UInt size,1201const Char * name_c,1202Int narg,1203const Char * nams_c,1204ObjFunc hdlr )1205{1206Obj name_o; /* name as an object */12071208/* convert the name to an object */1209C_NEW_STRING_DYN(name_o, name_c);1210RetypeBag(name_o, T_STRING+IMMUTABLE);12111212/* make the function */1213return NewFunctionT( type, size, name_o, narg, ArgStringToList( nams_c ), hdlr );1214}121512161217/****************************************************************************1218**1219*F ArgStringToList( <nams_c> )1220**1221** 'ArgStringToList' takes a C string <nams_c> containing a list of comma1222** separated argument names, and turns it into a plist of strings, ready1223** to be passed to 'NewFunction' as <nams>.1224*/1225Obj ArgStringToList(const Char *nams_c) {1226Obj tmp; /* argument name as an object */1227Obj nams_o; /* nams as an object */1228UInt len; /* length */1229UInt i, k, l; /* loop variables */12301231/* convert the arguments list to an object */1232len = 0;1233for ( k = 0; nams_c[k] != '\0'; k++ ) {1234if ( (0 == k || nams_c[k-1] == ' ' || nams_c[k-1] == ',')1235&& ( nams_c[k ] != ' ' && nams_c[k ] != ',') ) {1236len++;1237}1238}1239nams_o = NEW_PLIST( T_PLIST, len );1240SET_LEN_PLIST( nams_o, len );1241k = 0;1242for ( i = 1; i <= len; i++ ) {1243while ( nams_c[k] == ' ' || nams_c[k] == ',' ) {1244k++;1245}1246l = k;1247while ( nams_c[l] != ' ' && nams_c[l] != ',' && nams_c[l] != '\0' ) {1248l++;1249}1250C_NEW_STRING( tmp, l - k, nams_c + k );1251RetypeBag( tmp, T_STRING+IMMUTABLE );1252SET_ELM_PLIST( nams_o, i, tmp );1253k = l;1254}12551256return nams_o;1257}125812591260/****************************************************************************1261**12621263*F * * * * * * * * * * * * * type and print function * * * * * * * * * * * *1264*/12651266/****************************************************************************1267**12681269*F TypeFunction( <func> ) . . . . . . . . . . . . . . . type of a function1270**1271** 'TypeFunction' returns the type of the function <func>.1272**1273** 'TypeFunction' is the function in 'TypeObjFuncs' for functions.1274*/1275Obj TYPE_FUNCTION;1276Obj TYPE_OPERATION;12771278Obj TypeFunction (1279Obj func )1280{1281return ( IS_OPERATION(func) ? TYPE_OPERATION : TYPE_FUNCTION );1282}1283128412851286/****************************************************************************1287**1288*F PrintFunction( <func> ) . . . . . . . . . . . . . . . print a function1289**1290*/12911292Obj PrintOperation;12931294void PrintFunction (1295Obj func )1296{1297Int narg; /* number of arguments */1298Int nloc; /* number of locals */1299Obj oldLVars; /* terrible hack */1300UInt i; /* loop variable */1301UInt isvarg; /* does function have varargs? */13021303isvarg = 0;13041305if ( IS_OPERATION(func) ) {1306CALL_1ARGS( PrintOperation, func );1307return;1308}13091310/* print 'function (' */1311Pr("%5>function%< ( %>",0L,0L);13121313/* print the arguments */1314narg = NARG_FUNC(func);1315if (narg < 0) {1316isvarg = 1;1317narg = -narg;1318}13191320for ( i = 1; i <= narg; i++ ) {1321if ( NAMS_FUNC(func) != 0 )1322Pr( "%I", (Int)NAMI_FUNC( func, (Int)i ), 0L );1323else1324Pr( "<<arg-%d>>", (Int)i, 0L );1325if(isvarg && i == narg) {1326Pr("...", 0L, 0L);1327}1328if ( i != narg ) Pr("%<, %>",0L,0L);1329}1330Pr(" %<)",0L,0L);13311332Pr("\n",0L,0L);13331334/* print the locals */1335nloc = NLOC_FUNC(func);1336if ( nloc >= 1 ) {1337Pr("%>local ",0L,0L);1338for ( i = 1; i <= nloc; i++ ) {1339if ( NAMS_FUNC(func) != 0 )1340Pr( "%I", (Int)NAMI_FUNC( func, (Int)(narg+i) ), 0L );1341else1342Pr( "<<loc-%d>>", (Int)i, 0L );1343if ( i != nloc ) Pr("%<, %>",0L,0L);1344}1345Pr("%<;\n",0L,0L);1346}13471348/* print the body */1349if ( BODY_FUNC(func) == 0 || SIZE_OBJ(BODY_FUNC(func)) == NUMBER_HEADER_ITEMS_BODY*sizeof(Obj) ) {1350Pr("<<kernel or compiled code>>",0L,0L);1351}1352else {1353SWITCH_TO_NEW_LVARS( func, narg, NLOC_FUNC(func),1354oldLVars );1355PrintStat( FIRST_STAT_CURR_FUNC );1356SWITCH_TO_OLD_LVARS( oldLVars );1357}1358Pr("%4<\n",0L,0L);13591360/* print 'end' */1361Pr("end",0L,0L);1362}136313641365/****************************************************************************1366**1367*F FuncIS_FUNCTION( <self>, <func> ) . . . . . . . . . . . test for function1368**1369** 'FuncIS_FUNCTION' implements the internal function 'IsFunction'.1370**1371** 'IsFunction( <func> )'1372**1373** 'IsFunction' returns 'true' if <func> is a function and 'false'1374** otherwise.1375*/1376Obj IsFunctionFilt;13771378Obj FuncIS_FUNCTION (1379Obj self,1380Obj obj )1381{1382if ( TNUM_OBJ(obj) == T_FUNCTION ) {1383return True;1384}1385else if ( TNUM_OBJ(obj) < FIRST_EXTERNAL_TNUM ) {1386return False;1387}1388else {1389return DoFilter( self, obj );1390}1391}139213931394/****************************************************************************1395**1396*F FuncCALL_FUNC( <self>, <args> ) . . . . . . . . . . . . . call a function1397**1398** 'FuncCALL_FUNC' implements the internal function 'CallFunction'.1399**1400** 'CallFunction( <func>, <arg1>... )'1401**1402** 'CallFunction' calls the function <func> with the arguments <arg1>...,1403** i.e., it is equivalent to '<func>( <arg1>, <arg2>... )'.1404*/1405Obj CallFunctionOper;1406140714081409Obj FuncCALL_FUNC (1410Obj self,1411Obj args )1412{1413Obj result; /* result */1414Obj func; /* function */1415Obj list2; /* list of arguments */1416Obj arg; /* one argument */1417UInt i; /* loop variable */14181419/* the first argument is the function */1420if ( LEN_LIST( args ) == 0 ) {1421func = ErrorReturnObj(1422"usage: CallFunction( <func>, <arg1>... )",14230L, 0L,1424"you can replace function <func> via 'return <func>;'" );1425}1426else {1427func = ELMV_LIST( args, 1 );1428}14291430/* check that the first argument is a function */1431/*N 1996/06/26 mschoene this should be done by 'CALL_<i>ARGS' */1432while ( TNUM_OBJ( func ) != T_FUNCTION ) {1433func = ErrorReturnObj(1434"CallFunction: <func> must be a function",14350L, 0L,1436"you can replace function <func> via 'return <func>;'" );1437}14381439/* call the function */1440if ( LEN_LIST(args) == 1 ) {1441result = CALL_0ARGS( func );1442}1443else if ( LEN_LIST(args) == 2 ) {1444result = CALL_1ARGS( func, ELMV_LIST(args,2) );1445}1446else if ( LEN_LIST(args) == 3 ) {1447result = CALL_2ARGS( func, ELMV_LIST(args,2), ELMV_LIST(args,3) );1448}1449else if ( LEN_LIST(args) == 4 ) {1450result = CALL_3ARGS( func, ELMV_LIST(args,2), ELMV_LIST(args,3),1451ELMV_LIST(args,4) );1452}1453else if ( LEN_LIST(args) == 5 ) {1454result = CALL_4ARGS( func, ELMV_LIST(args,2), ELMV_LIST(args,3),1455ELMV_LIST(args,4), ELMV_LIST(args,5) );1456}1457else if ( LEN_LIST(args) == 6 ) {1458result = CALL_5ARGS( func, ELMV_LIST(args,2), ELMV_LIST(args,3),1459ELMV_LIST(args,4), ELMV_LIST(args,5),1460ELMV_LIST(args,6) );1461}1462else if ( LEN_LIST(args) == 7 ) {1463result = CALL_6ARGS( func, ELMV_LIST(args,2), ELMV_LIST(args,3),1464ELMV_LIST(args,4), ELMV_LIST(args,5),1465ELMV_LIST(args,6), ELMV_LIST(args,7) );1466}1467else {1468list2 = NEW_PLIST( T_PLIST, LEN_LIST(args)-1 );1469SET_LEN_PLIST( list2, LEN_LIST(args)-1 );1470for ( i = 1; i <= LEN_LIST(args)-1; i++ ) {1471arg = ELMV_LIST( args, (Int)(i+1) );1472SET_ELM_PLIST( list2, i, arg );1473}1474result = CALL_XARGS( func, list2 );1475}14761477/* return the result */1478return result;1479}148014811482/****************************************************************************1483**1484*F FuncCALL_FUNC_LIST( <self>, <func>, <list> ) . . . . . . call a function1485**1486** 'FuncCALL_FUNC_LIST' implements the internal function 'CallFuncList'.1487**1488** 'CallFuncList( <func>, <list> )'1489**1490** 'CallFuncList' calls the function <func> with the arguments list <list>,1491** i.e., it is equivalent to '<func>( <list>[1], <list>[2]... )'.1492*/1493Obj CallFuncListOper;14941495Obj CallFuncList ( Obj func, Obj list )1496{1497Obj result; /* result */1498Obj list2; /* list of arguments */1499Obj arg; /* one argument */1500UInt i; /* loop variable */150115021503if (TNUM_OBJ(func) == T_FUNCTION) {15041505/* call the function */1506if ( LEN_LIST(list) == 0 ) {1507result = CALL_0ARGS( func );1508}1509else if ( LEN_LIST(list) == 1 ) {1510result = CALL_1ARGS( func, ELMV_LIST(list,1) );1511}1512else if ( LEN_LIST(list) == 2 ) {1513result = CALL_2ARGS( func, ELMV_LIST(list,1), ELMV_LIST(list,2) );1514}1515else if ( LEN_LIST(list) == 3 ) {1516result = CALL_3ARGS( func, ELMV_LIST(list,1), ELMV_LIST(list,2),1517ELMV_LIST(list,3) );1518}1519else if ( LEN_LIST(list) == 4 ) {1520result = CALL_4ARGS( func, ELMV_LIST(list,1), ELMV_LIST(list,2),1521ELMV_LIST(list,3), ELMV_LIST(list,4) );1522}1523else if ( LEN_LIST(list) == 5 ) {1524result = CALL_5ARGS( func, ELMV_LIST(list,1), ELMV_LIST(list,2),1525ELMV_LIST(list,3), ELMV_LIST(list,4),1526ELMV_LIST(list,5) );1527}1528else if ( LEN_LIST(list) == 6 ) {1529result = CALL_6ARGS( func, ELMV_LIST(list,1), ELMV_LIST(list,2),1530ELMV_LIST(list,3), ELMV_LIST(list,4),1531ELMV_LIST(list,5), ELMV_LIST(list,6) );1532}1533else {1534list2 = NEW_PLIST( T_PLIST, LEN_LIST(list) );1535SET_LEN_PLIST( list2, LEN_LIST(list) );1536for ( i = 1; i <= LEN_LIST(list); i++ ) {1537arg = ELMV_LIST( list, (Int)i );1538SET_ELM_PLIST( list2, i, arg );1539}1540result = CALL_XARGS( func, list2 );1541}1542} else {1543result = DoOperation2Args(CallFuncListOper, func, list);1544}1545/* return the result */1546return result;15471548}15491550Obj FuncCALL_FUNC_LIST (1551Obj self,1552Obj func,1553Obj list )1554{1555/* check that the second argument is a list */1556while ( ! IS_SMALL_LIST( list ) ) {1557list = ErrorReturnObj(1558"CallFuncList: <list> must be a small list",15590L, 0L,1560"you can replace <list> via 'return <list>;'" );1561}1562return CallFuncList(func, list);1563}15641565/****************************************************************************1566**15671568*F * * * * * * * * * * * * * * * utility functions * * * * * * * * * * * * *1569*/15701571/****************************************************************************1572**1573*F FuncNAME_FUNC( <self>, <func> ) . . . . . . . . . . . name of a function1574*/1575Obj NAME_FUNC_Oper;1576Obj SET_NAME_FUNC_Oper;15771578Obj FuncNAME_FUNC (1579Obj self,1580Obj func )1581{1582Obj name;15831584if ( TNUM_OBJ(func) == T_FUNCTION ) {1585name = NAME_FUNC(func);1586if ( name == 0 ) {1587C_NEW_STRING_CONST(name, "unknown");1588RetypeBag(name, T_STRING+IMMUTABLE);1589NAME_FUNC(func) = name;1590CHANGED_BAG(func);1591}1592return name;1593}1594else {1595return DoOperation1Args( self, func );1596}1597}15981599Obj FuncSET_NAME_FUNC(1600Obj self,1601Obj func,1602Obj name )1603{1604while (!IsStringConv(name)) {1605name = ErrorReturnObj("SET_NAME_FUNC( <func>, <name> ): <name> must be a string, not a %s",1606(Int)TNAM_OBJ(name), 0, "YOu can return a new name to continue");1607}1608if (TNUM_OBJ(func) == T_FUNCTION ) {1609NAME_FUNC(func) = name;1610CHANGED_BAG(func);1611} else1612DoOperation2Args(SET_NAME_FUNC_Oper, func, name);1613return (Obj) 0;1614}161516161617/****************************************************************************1618**1619*F FuncNARG_FUNC( <self>, <func> ) . . . . number of arguments of a function1620*/1621Obj NARG_FUNC_Oper;16221623Obj FuncNARG_FUNC (1624Obj self,1625Obj func )1626{1627if ( TNUM_OBJ(func) == T_FUNCTION ) {1628return INTOBJ_INT( NARG_FUNC(func) );1629}1630else {1631return DoOperation1Args( self, func );1632}1633}163416351636/****************************************************************************1637**1638*F FuncNAMS_FUNC( <self>, <func> ) . . . . names of local vars of a function1639*/1640Obj NAMS_FUNC_Oper;16411642Obj FuncNAMS_FUNC (1643Obj self,1644Obj func )1645{1646Obj nams;1647if ( TNUM_OBJ(func) == T_FUNCTION ) {1648nams = NAMS_FUNC(func);1649return (nams != (Obj)0) ? nams : Fail;1650}1651else {1652return DoOperation1Args( self, func );1653}1654}165516561657/****************************************************************************1658**1659*F FuncPROF_FUNC( <self>, <func> ) . . . . . . profiling info of a function1660*/1661Obj PROF_FUNC_Oper;16621663Obj FuncPROF_FUNC (1664Obj self,1665Obj func )1666{1667Obj prof;16681669if ( TNUM_OBJ(func) == T_FUNCTION ) {1670prof = PROF_FUNC(func);1671if ( TNUM_OBJ(prof) == T_FUNCTION ) {1672return PROF_FUNC(prof);1673} else {1674return prof;1675}1676}1677else {1678return DoOperation1Args( self, func );1679}1680}168116821683/****************************************************************************1684**16851686*F FuncCLEAR_PROFILE_FUNC( <self>, <func> ) . . . . . . . . . clear profile1687*/1688Obj FuncCLEAR_PROFILE_FUNC(1689Obj self,1690Obj func )1691{1692Obj prof;16931694/* check the argument */1695if ( TNUM_OBJ(func) != T_FUNCTION ) {1696ErrorQuit( "<func> must be a function", 0L, 0L );1697return 0;1698}16991700/* clear profile info */1701prof = PROF_FUNC(func);1702if ( prof == 0 ) {1703ErrorQuit( "<func> has corrupted profile info", 0L, 0L );1704return 0;1705}1706if ( TNUM_OBJ(prof) == T_FUNCTION ) {1707prof = PROF_FUNC(prof);1708}1709if ( prof == 0 ) {1710ErrorQuit( "<func> has corrupted profile info", 0L, 0L );1711return 0;1712}1713SET_COUNT_PROF( prof, 0 );1714SET_TIME_WITH_PROF( prof, 0 );1715SET_TIME_WOUT_PROF( prof, 0 );1716SET_STOR_WITH_PROF( prof, 0 );1717SET_STOR_WOUT_PROF( prof, 0 );17181719return (Obj)0;1720}172117221723/****************************************************************************1724**1725*F FuncPROFILE_FUNC( <self>, <func> ) . . . . . . . . . . . . start profile1726*/1727Obj FuncPROFILE_FUNC(1728Obj self,1729Obj func )1730{1731Obj prof;1732Obj copy;17331734/* check the argument */1735if ( TNUM_OBJ(func) != T_FUNCTION ) {1736ErrorQuit( "<func> must be a function", 0L, 0L );1737return 0;1738}1739/* uninstall trace handler */1740ChangeDoOperations( func, 0 );17411742/* install profiling */1743prof = PROF_FUNC(func);17441745/* install new handlers */1746if ( TNUM_OBJ(prof) != T_FUNCTION ) {1747copy = NewBag( TNUM_OBJ(func), SIZE_OBJ(func) );1748HDLR_FUNC(copy,0) = HDLR_FUNC(func,0);1749HDLR_FUNC(copy,1) = HDLR_FUNC(func,1);1750HDLR_FUNC(copy,2) = HDLR_FUNC(func,2);1751HDLR_FUNC(copy,3) = HDLR_FUNC(func,3);1752HDLR_FUNC(copy,4) = HDLR_FUNC(func,4);1753HDLR_FUNC(copy,5) = HDLR_FUNC(func,5);1754HDLR_FUNC(copy,6) = HDLR_FUNC(func,6);1755HDLR_FUNC(copy,7) = HDLR_FUNC(func,7);1756NAME_FUNC(copy) = NAME_FUNC(func);1757NARG_FUNC(copy) = NARG_FUNC(func);1758NAMS_FUNC(copy) = NAMS_FUNC(func);1759PROF_FUNC(copy) = PROF_FUNC(func);1760HDLR_FUNC(func,0) = DoProf0args;1761HDLR_FUNC(func,1) = DoProf1args;1762HDLR_FUNC(func,2) = DoProf2args;1763HDLR_FUNC(func,3) = DoProf3args;1764HDLR_FUNC(func,4) = DoProf4args;1765HDLR_FUNC(func,5) = DoProf5args;1766HDLR_FUNC(func,6) = DoProf6args;1767HDLR_FUNC(func,7) = DoProfXargs;1768PROF_FUNC(func) = copy;1769CHANGED_BAG(func);1770}17711772return (Obj)0;1773}177417751776/****************************************************************************1777**1778*F FuncIS_PROFILED_FUNC( <self>, <func> ) . . check if function is profiled1779*/1780Obj FuncIS_PROFILED_FUNC(1781Obj self,1782Obj func )1783{1784/* check the argument */1785if ( TNUM_OBJ(func) != T_FUNCTION ) {1786ErrorQuit( "<func> must be a function", 0L, 0L );1787return 0;1788}1789return ( TNUM_OBJ(PROF_FUNC(func)) != T_FUNCTION ) ? False : True;1790}17911792Obj FuncFILENAME_FUNC(Obj self, Obj func) {17931794/* check the argument */1795if ( TNUM_OBJ(func) != T_FUNCTION ) {1796ErrorQuit( "<func> must be a function", 0L, 0L );1797return 0;1798}17991800if (BODY_FUNC(func)) {1801Obj fn = FILENAME_BODY(BODY_FUNC(func));1802#ifndef WARD_ENABLED1803if (fn) {1804return fn;1805}1806#endif1807}1808return Fail;1809}18101811Obj FuncSTARTLINE_FUNC(Obj self, Obj func) {18121813/* check the argument */1814if ( TNUM_OBJ(func) != T_FUNCTION ) {1815ErrorQuit( "<func> must be a function", 0L, 0L );1816return 0;1817}18181819if (BODY_FUNC(func)) {1820Obj sl = STARTLINE_BODY(BODY_FUNC(func));1821if (sl)1822return sl;1823}1824return Fail;1825}18261827Obj FuncENDLINE_FUNC(Obj self, Obj func) {18281829/* check the argument */1830if ( TNUM_OBJ(func) != T_FUNCTION ) {1831ErrorQuit( "<func> must be a function", 0L, 0L );1832return 0;1833}18341835if (BODY_FUNC(func)) {1836Obj el = ENDLINE_BODY(BODY_FUNC(func));1837if (el)1838return el;1839}1840return Fail;1841}184218431844/****************************************************************************1845**1846*F FuncUNPROFILE_FUNC( <self>, <func> ) . . . . . . . . . . . stop profile1847*/1848Obj FuncUNPROFILE_FUNC(1849Obj self,1850Obj func )1851{1852Obj prof;18531854/* check the argument */1855if ( TNUM_OBJ(func) != T_FUNCTION ) {1856ErrorQuit( "<func> must be a function", 0L, 0L );1857return 0;1858}18591860/* uninstall trace handler */1861ChangeDoOperations( func, 0 );18621863/* profiling is active, restore handlers */1864prof = PROF_FUNC(func);1865if ( TNUM_OBJ(prof) == T_FUNCTION ) {1866HDLR_FUNC(func,0) = HDLR_FUNC(prof,0);1867HDLR_FUNC(func,1) = HDLR_FUNC(prof,1);1868HDLR_FUNC(func,2) = HDLR_FUNC(prof,2);1869HDLR_FUNC(func,3) = HDLR_FUNC(prof,3);1870HDLR_FUNC(func,4) = HDLR_FUNC(prof,4);1871HDLR_FUNC(func,5) = HDLR_FUNC(prof,5);1872HDLR_FUNC(func,6) = HDLR_FUNC(prof,6);1873HDLR_FUNC(func,7) = HDLR_FUNC(prof,7);1874PROF_FUNC(func) = PROF_FUNC(prof);1875CHANGED_BAG(func);1876}18771878return (Obj)0;1879}18801881Obj FuncIsKernelFunction(Obj self, Obj func) {1882if (!IS_FUNC(func))1883return Fail;1884else return (BODY_FUNC(func) == 0 || SIZE_OBJ(BODY_FUNC(func)) == 0) ? True : False;1885}18861887Obj FuncHandlerCookieOfFunction(Obj self, Obj func)1888{1889Int narg;1890ObjFunc hdlr;1891const Char *cookie;1892Obj cookieStr;1893if (!IS_FUNC(func))1894return Fail;1895narg = NARG_FUNC(func);1896if (narg == -1)1897narg = 7;1898hdlr = HDLR_FUNC(func, narg);1899cookie = CookieOfHandler(hdlr);1900C_NEW_STRING_DYN(cookieStr, cookie);1901return cookieStr;1902}19031904/****************************************************************************1905**19061907*F SaveFunction( <func> ) . . . . . . . . . . . . . . . . . save a function1908**1909*/1910void SaveFunction ( Obj func )1911{1912UInt i;1913for (i = 0; i <= 7; i++)1914SaveHandler(HDLR_FUNC(func,i));1915SaveSubObj(NAME_FUNC(func));1916SaveUInt(NARG_FUNC(func));1917SaveSubObj(NAMS_FUNC(func));1918SaveSubObj(PROF_FUNC(func));1919SaveUInt(NLOC_FUNC(func));1920SaveSubObj(BODY_FUNC(func));1921SaveSubObj(ENVI_FUNC(func));1922SaveSubObj(FEXS_FUNC(func));1923if (SIZE_OBJ(func) != SIZE_FUNC)1924SaveOperationExtras( func );1925}19261927/****************************************************************************1928**1929*F LoadFunction( <func> ) . . . . . . . . . . . . . . . . . load a function1930**1931*/1932void LoadFunction ( Obj func )1933{1934UInt i;1935for (i = 0; i <= 7; i++)1936HDLR_FUNC(func,i) = LoadHandler();1937NAME_FUNC(func) = LoadSubObj();1938NARG_FUNC(func) = LoadUInt();1939NAMS_FUNC(func) = LoadSubObj();1940PROF_FUNC(func) = LoadSubObj();1941NLOC_FUNC(func) = LoadUInt();1942BODY_FUNC(func) = LoadSubObj();1943ENVI_FUNC(func) = LoadSubObj();1944FEXS_FUNC(func) = LoadSubObj();1945if (SIZE_OBJ(func) != SIZE_FUNC)1946LoadOperationExtras( func );1947}194819491950/****************************************************************************1951**19521953*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *1954*/19551956/****************************************************************************1957**19581959*V GVarFilts . . . . . . . . . . . . . . . . . . . list of filters to export1960*/1961static StructGVarFilt GVarFilts [] = {19621963{ "IS_FUNCTION", "obj", &IsFunctionFilt,1964FuncIS_FUNCTION, "src/calls.c:IS_FUNCTION" },19651966{ 0 }19671968};196919701971/****************************************************************************1972**1973*V GVarOpers . . . . . . . . . . . . . . . . . list of operations to export1974*/1975static StructGVarOper GVarOpers [] = {19761977{ "CALL_FUNC", -1, "args", &CallFunctionOper,1978FuncCALL_FUNC, "src/calls.c:CALL_FUNC" },19791980{ "CALL_FUNC_LIST", 2, "func, list", &CallFuncListOper,1981FuncCALL_FUNC_LIST, "src/calls.c:CALL_FUNC_LIST" },19821983{ "NAME_FUNC", 1, "func", &NAME_FUNC_Oper,1984FuncNAME_FUNC, "src/calls.c:NAME_FUNC" },19851986{ "SET_NAME_FUNC", 2, "func, name", &SET_NAME_FUNC_Oper,1987FuncSET_NAME_FUNC, "src/calls.c:SET_NAME_FUNC" },19881989{ "NARG_FUNC", 1, "func", &NARG_FUNC_Oper,1990FuncNARG_FUNC, "src/calls.c:NARG_FUNC" },19911992{ "NAMS_FUNC", 1, "func", &NAMS_FUNC_Oper,1993FuncNAMS_FUNC, "src/calls.c:NAMS_FUNC" },19941995{ "PROF_FUNC", 1, "func", &PROF_FUNC_Oper,1996FuncPROF_FUNC, "src/calls.c:PROF_FUNC" },199719981999{ 0 }20002001};200220032004/****************************************************************************2005**2006*V GVarFuncs . . . . . . . . . . . . . . . . . . list of functions to export2007*/2008static StructGVarFunc GVarFuncs [] = {20092010{ "CLEAR_PROFILE_FUNC", 1, "func",2011FuncCLEAR_PROFILE_FUNC, "src/calls.c:CLEAR_PROFILE_FUNC" },20122013{ "IS_PROFILED_FUNC", 1, "func",2014FuncIS_PROFILED_FUNC, "src/calls.c:IS_PROFILED_FUNC" },20152016{ "PROFILE_FUNC", 1, "func",2017FuncPROFILE_FUNC, "src/calls.c:PROFILE_FUNC" },20182019{ "UNPROFILE_FUNC", 1, "func",2020FuncUNPROFILE_FUNC, "src/calls.c:UNPROFILE_FUNC" },20212022{ "IsKernelFunction", 1, "func",2023FuncIsKernelFunction, "src/calls.c:IsKernelFunction" },20242025{ "HandlerCookieOfFunction", 1, "func",2026FuncHandlerCookieOfFunction, "src/calls.c:HandlerCookieOfFunction" },20272028{ "FILENAME_FUNC", 1, "func",2029FuncFILENAME_FUNC, "src/calls.c:FILENAME_FUNC" },20302031{ "STARTLINE_FUNC", 1, "func",2032FuncSTARTLINE_FUNC, "src/calls.c:STARTLINE_FUNC" },20332034{ "ENDLINE_FUNC", 1, "func",2035FuncENDLINE_FUNC, "src/calls.c:ENDLINE_FUNC" },2036{ 0 }20372038};203920402041/****************************************************************************2042**20432044*F InitKernel( <module> ) . . . . . . . . initialise kernel data structures2045*/2046static Int InitKernel (2047StructInitInfo * module )2048{20492050/* install the marking functions */2051InfoBags[ T_FUNCTION ].name = "function";2052InitMarkFuncBags( T_FUNCTION , MarkAllSubBags );20532054/* install the type functions */2055ImportGVarFromLibrary( "TYPE_FUNCTION", &TYPE_FUNCTION );2056ImportGVarFromLibrary( "TYPE_OPERATION", &TYPE_OPERATION );2057TypeObjFuncs[ T_FUNCTION ] = TypeFunction;20582059/* init filters and functions */2060InitHdlrFiltsFromTable( GVarFilts );2061InitHdlrOpersFromTable( GVarOpers );2062InitHdlrFuncsFromTable( GVarFuncs );20632064/* and the saving function */2065SaveObjFuncs[ T_FUNCTION ] = SaveFunction;2066LoadObjFuncs[ T_FUNCTION ] = LoadFunction;20672068/* install the printer */2069InitFopyGVar( "PRINT_OPERATION", &PrintOperation );2070PrintObjFuncs[ T_FUNCTION ] = PrintFunction;207120722073/* initialise all 'Do<Something><N>args' handlers, give the most */2074/* common ones short cookies to save space in in the saved workspace */2075InitHandlerFunc( DoFail0args, "f0" );2076InitHandlerFunc( DoFail1args, "f1" );2077InitHandlerFunc( DoFail2args, "f2" );2078InitHandlerFunc( DoFail3args, "f3" );2079InitHandlerFunc( DoFail4args, "f4" );2080InitHandlerFunc( DoFail5args, "f5" );2081InitHandlerFunc( DoFail6args, "f6" );2082InitHandlerFunc( DoFailXargs, "f7" );20832084InitHandlerFunc( DoWrap0args, "w0" );2085InitHandlerFunc( DoWrap1args, "w1" );2086InitHandlerFunc( DoWrap2args, "w2" );2087InitHandlerFunc( DoWrap3args, "w3" );2088InitHandlerFunc( DoWrap4args, "w4" );2089InitHandlerFunc( DoWrap5args, "w5" );2090InitHandlerFunc( DoWrap6args, "w6" );20912092InitHandlerFunc( DoProf0args, "p0" );2093InitHandlerFunc( DoProf1args, "p1" );2094InitHandlerFunc( DoProf2args, "p2" );2095InitHandlerFunc( DoProf3args, "p3" );2096InitHandlerFunc( DoProf4args, "p4" );2097InitHandlerFunc( DoProf5args, "p5" );2098InitHandlerFunc( DoProf6args, "p6" );2099InitHandlerFunc( DoProfXargs, "pX" );21002101/* return success */2102return 0;2103}210421052106/****************************************************************************2107**2108*F InitLibrary( <module> ) . . . . . . . initialise library data structures2109*/2110static Int InitLibrary (2111StructInitInfo * module ){2112/* init filters and functions */2113InitGVarFiltsFromTable( GVarFilts );2114InitGVarOpersFromTable( GVarOpers );2115InitGVarFuncsFromTable( GVarFuncs );21162117/* return success */2118return 0;2119}212021212122/****************************************************************************2123**2124*F InitInfoCalls() . . . . . . . . . . . . . . . . . table of init functions2125*/2126static StructInitInfo module = {2127MODULE_BUILTIN, /* type */2128"calls", /* name */21290, /* revision entry of c file */21300, /* revision entry of h file */21310, /* version */21320, /* crc */2133InitKernel, /* initKernel */2134InitLibrary, /* initLibrary */21350, /* checkInit */21360, /* preSave */21370, /* postSave */21380 /* postRestore */2139};21402141StructInitInfo * InitInfoCalls ( void )2142{2143return &module;2144}214521462147/****************************************************************************2148**21492150*E calls.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here2151*/215221532154