From 17d1bac642a3f8c03c8e24cd4492711efdd867b3 Mon Sep 17 00:00:00 2001 From: Steve Linton Date: Wed, 12 Sep 2018 14:53:40 +0200 Subject: [PATCH] Reorder methods after new implications are added Many GAP methods get rank adjustments based on the rank of some filter, e.g, `RankFilter(IsAbelian)`. However, these ranks may change when new implications are added, e.g. when certain packages are loaded. But those method rank adjustments then won't be updated, which can ultimately lead to the effect that loading a package changes which methods get executed in otherwise identical code. This PR helps avoid that, by making it possible to set "dynamic" rank adjustments which get updated as new implications are added. Some cleverness is needed to make this work efficiently when loading packages. - Record rank adjustment in METHODS_OPERATION - Add RECALCULATE_ALL_METHOD_RANKS function which does what it says. - Adjust MethodsOperation to include base rank - Increase size of HIDDEN_IMPS_CACHE and WITH_IMPS_CACHE to speed up RECALCULATE_ALL_METHOD_RANKS() - Make sure RANK_FILTERS is always set promptly, then remove the test for it being unset in RankFilter - Automatically reorder methods after library or package loading, or InstallTrueMethod - Use COPY_LIST_ENTRIES in method installation to avoid making an intermediate list - Support passing a function of no arguments as the rank adjustment to InstallMethod - Reset reordering status on quit from break loop. Fixes #2513 --- doc/ref/methsel.xml | 1 + lib/error.g | 3 + lib/filter.g | 73 +++++++++ lib/init.g | 3 + lib/oper.g | 130 +++++++++++++++- lib/oper1.g | 28 +++- lib/package.gi | 14 +- src/c_oper1.c | 205 ++++++++++++++++++-------- src/c_type1.c | 4 +- src/hpc/c_oper1.c | 205 ++++++++++++++++++-------- src/hpc/c_type1.c | 4 +- src/opers.c | 9 +- tst/testinstall/method-rankfns.tst | 21 +++ tst/testinstall/method-reordering.tst | 35 +++++ tst/testinstall/triviso.tst | 4 +- tst/testinstall/varargs.tst | 2 +- 16 files changed, 589 insertions(+), 152 deletions(-) create mode 100644 tst/testinstall/method-rankfns.tst create mode 100644 tst/testinstall/method-reordering.tst diff --git a/doc/ref/methsel.xml b/doc/ref/methsel.xml index 17543a9549..de75cfd1ac 100644 --- a/doc/ref/methsel.xml +++ b/doc/ref/methsel.xml @@ -252,6 +252,7 @@ one can install also immediate methods. Logical Implications <#Include Label="InstallTrueMethod"> +<#Include Label="MethodReordering"> diff --git a/lib/error.g b/lib/error.g index 74bc769450..ff636977d1 100644 --- a/lib/error.g +++ b/lib/error.g @@ -32,6 +32,9 @@ BIND_GLOBAL( "OnQuit", # care to ensure it always has a definition. - GG until IsEmpty(OptionsStack); Info(InfoWarning,1,"Options stack has been reset"); fi; + if IsBound(ResetMethodReordering) and IsFunction(ResetMethodReordering) then + ResetMethodReordering(); + fi; end); diff --git a/lib/filter.g b/lib/filter.g index 96d819e4ed..2416194868 100644 --- a/lib/filter.g +++ b/lib/filter.g @@ -184,6 +184,64 @@ BIND_GLOBAL( "InstallTrueMethodNewFilter", function ( tofilt, from ) end ); +############################################################################# +## +#F SuspendMethodReordering( ) +#F ResumeMethodReordering( ) +#F ResetMethodReordering( ) +## +## <#GAPDoc Label="MethodReordering"> +## +## +## +## +## +## +## These functions control whether the method reordering process described +## in is invoked or not. Since this process +## can be comparatively time-consuming, it is usually suspended when a lot +## of implications are due to be installed, for instance when loading the +## library, or a package. This is done by calling +## once the installations are done, +## should be called. These pairs of calls +## can be nested. When the outermost pair is complete, method reordering +## takes place and is enabled in thereafter. +## +## effectively exits all nested suspensions, +## resuming reordering immediately. This function is mainly provided for +## error recovery and similar purposes and is called on quitting from a +## break loop. +## +## +## <#/GAPDoc> + +# +# This function will be defined in oper.g +# +RECALCULATE_ALL_METHOD_RANKS := fail; + +REORDER_METHODS_SUSPENSION_LEVEL := 1; + +BIND_GLOBAL( "SuspendMethodReordering", function() + REORDER_METHODS_SUSPENSION_LEVEL := REORDER_METHODS_SUSPENSION_LEVEL + 1; +end); + + +BIND_GLOBAL( "ResumeMethodReordering", function() + if REORDER_METHODS_SUSPENSION_LEVEL > 0 then + REORDER_METHODS_SUSPENSION_LEVEL := REORDER_METHODS_SUSPENSION_LEVEL - 1; + fi; + if REORDER_METHODS_SUSPENSION_LEVEL <= 0 then + RECALCULATE_ALL_METHOD_RANKS(); + fi; +end); + +BIND_GLOBAL( "ResetMethodReordering", function() + REORDER_METHODS_SUSPENSION_LEVEL := 0; + RECALCULATE_ALL_METHOD_RANKS(); +end); + + ############################################################################# ## #F InstallTrueMethod( , ) @@ -223,10 +281,19 @@ end ); ## one can rely on the fact that every object in the filter ## IsGroup and IsCyclic will also be in the filter ## . +##

+## Adding logical implications can change the rank of filters (see +## ) and consequently the rank, and so choice of +## methods for operations (see ). +## By default InstallTrueMethod adjusts the method selection data +## structures to take care of this, but this process can be time-consuming, +## so functions and +## are provided to allow control of this process. ## ## ## <#/GAPDoc> ## + BIND_GLOBAL( "InstallTrueMethod", function ( tofilt, from ) InstallTrueMethodNewFilter( tofilt, from ); @@ -234,6 +301,12 @@ BIND_GLOBAL( "InstallTrueMethod", function ( tofilt, from ) # clear the caches because we do not know if filter is new CLEAR_HIDDEN_IMP_CACHE( from ); CLEAR_IMP_CACHE(); + + # maybe rerank methods to take account of new implication + if REORDER_METHODS_SUSPENSION_LEVEL = 0 then + RECALCULATE_ALL_METHOD_RANKS(); + fi; + end ); diff --git a/lib/init.g b/lib/init.g index ff2c69745e..43ed516b0a 100644 --- a/lib/init.g +++ b/lib/init.g @@ -1013,6 +1013,9 @@ fi; ## ## Read init files, run a shell, and do exit-time processing. ## + +ResumeMethodReordering(); + InstallAndCallPostRestore( function() local i, status; for i in [1..Length(GAPInfo.InitFiles)] do diff --git a/lib/oper.g b/lib/oper.g index bcbf31b757..cd426a6711 100644 --- a/lib/oper.g +++ b/lib/oper.g @@ -1902,7 +1902,7 @@ end); fi; -if BASE_SIZE_METHODS_OPER_ENTRY <> 5 then +if BASE_SIZE_METHODS_OPER_ENTRY <> 6 then Error("MethodsOperation must be updated for new BASE_SIZE_METHODS_OPER_ENTRY"); fi; @@ -1923,6 +1923,7 @@ BIND_GLOBAL("MethodsOperation", function(oper, nargs) func := meths[i + nargs + 2], rank := meths[i + nargs + 3], info := meths[i + nargs + 4], + rankbase := meths[i + nargs + 6], ); ADD_LIST(result, m); if IsBound(meths[i + nargs + 5]) then @@ -1932,6 +1933,133 @@ BIND_GLOBAL("MethodsOperation", function(oper, nargs) return result; end ); +############################################################################# +## +#F RECALCULATE_ALL_METHOD_RANKS() . . reorder methods after new implications +## +## Installing new implications (including hidden implications) can change the +## rank of existing filters, and so of existing methods for operations. +## +## This function recalculates all such ranks and adjusts the method ordering +## where needed. If the ordering changes, the relevant caches are flushed. +## +## If PRINT_REORDERED_METHODS is true, it prints some diagnostics (this is a +## bit too low-level for Info). +## +## + + +# +# We had to install a placeholder for this in filter.g +# +Unbind(RECALCULATE_ALL_METHOD_RANKS); + +PRINT_REORDERED_METHODS := false; + +BIND_GLOBAL( "RECALCULATE_ALL_METHOD_RANKS", function() + local oper, n, changed, meths, nmethods, i, base, rank, j, req, + req2, k, l; + + for oper in OPERATIONS do + for n in [0..6] do + changed := false; + meths := METHODS_OPERATION(oper, n); + nmethods := LENGTH(meths)/(BASE_SIZE_METHODS_OPER_ENTRY+n); + if IS_CONSTRUCTOR(oper) and n > 0 then + for i in [nmethods,nmethods-1..1] do + base := (i-1)*(BASE_SIZE_METHODS_OPER_ENTRY+n); + # data for this method is meths{[base+1..base+BASE_SIZE_METHODS_OPER_ENTRY + n]} + rank := meths[base+6+n]; + if IS_FUNCTION(rank) then + rank := rank(); + fi; + rank := rank - RankFilter(WITH_IMPS_FLAGS(meths[base+2])); + if rank <> meths[base+n+3] then + if IsHPCGAP and not changed then + meths := SHALLOW_COPY_OBJ(meths); + fi; + changed := true; + meths[base+n+3] := rank; + fi; + # compare to rank of succeding method + if i = nmethods or rank >= meths[base+BASE_SIZE_METHODS_OPER_ENTRY + 2*n + 3] then + continue; + fi; + k := i+2; + while k <= nmethods and meths[(k-1)*(BASE_SIZE_METHODS_OPER_ENTRY+n) + n + 3] < rank do + k := k+1; + od; + k := k-1; + if PRINT_REORDERED_METHODS then + Print("Constructor ",NAME_FUNC(oper), " ", n," args. Moving method ",i," (", + meths[base+n+4]," from ",meths[base+n+5][1],":", meths[base+n+5][2], + ") to position ",k,"\n"); + fi; + l := meths{[base+1..base+n+BASE_SIZE_METHODS_OPER_ENTRY]}; + COPY_LIST_ENTRIES(meths, 1 + i*(n+BASE_SIZE_METHODS_OPER_ENTRY), 1, + meths, 1 +(i-1)*(n+BASE_SIZE_METHODS_OPER_ENTRY), 1, + (k-i)*(n+BASE_SIZE_METHODS_OPER_ENTRY)); + meths{[1 + (k-1)*(n+BASE_SIZE_METHODS_OPER_ENTRY).. + k*(n+BASE_SIZE_METHODS_OPER_ENTRY)]} := l; + od; + else + for i in [1 ..nmethods] do + base := (i-1)*(BASE_SIZE_METHODS_OPER_ENTRY+n); + # data for this method is meths{[base+1..base+BASE_SIZE_METHODS_OPER_ENTRY + n]} + rank := meths[base+6+n]; + if IS_FUNCTION(rank) then + rank := rank(); + fi; + + + for j in [1..n] do + req := meths[base+1+j]; + rank := rank+RankFilter(WITH_IMPS_FLAGS(req)); + od; + + if rank <> meths[base+n+3] then + if IsHPCGAP and not changed then + meths := SHALLOW_COPY_OBJ(meths); + fi; + changed := true; + meths[base+n+3] := rank; + fi; + + # compare to rank of preceding method + if i = 1 or rank <= meths[base-BASE_SIZE_METHODS_OPER_ENTRY+3] then + continue; + fi; + + k := i-2; + while k > 1 and meths[(k-1)*(BASE_SIZE_METHODS_OPER_ENTRY+n) + n + 3] < rank do + k := k-1; + od; + k := k+1; + if PRINT_REORDERED_METHODS then + Print(NAME_FUNC(oper), " ", n," args. Moving method ",i," (", + meths[base+n+4]," from ",meths[base+n+5][1],":", meths[base+n+5][2], + ") to position ",k,"\n"); + fi; + l := meths{[base+1..base+n+BASE_SIZE_METHODS_OPER_ENTRY]}; + COPY_LIST_ENTRIES(meths, 1 + (k-1)*(n+BASE_SIZE_METHODS_OPER_ENTRY), 1, + meths, 1 + k*(n+BASE_SIZE_METHODS_OPER_ENTRY), 1, + (i-k)*(n+BASE_SIZE_METHODS_OPER_ENTRY)); + meths{[1 + (k-1)*(n+BASE_SIZE_METHODS_OPER_ENTRY).. + k*(n+BASE_SIZE_METHODS_OPER_ENTRY)]} := l; + od; + fi; + if changed then + if IsHPCGAP then + SET_METHODS_OPERATION(oper,n,MakeReadOnlySingleObj(meths)); + else + CHANGED_METHODS_OPERATION(oper,n); + fi; + fi; + od; + od; +end ); + + ############################################################################# ## #E diff --git a/lib/oper1.g b/lib/oper1.g index 4a7e9bf5a3..d2d78341fe 100644 --- a/lib/oper1.g +++ b/lib/oper1.g @@ -143,8 +143,8 @@ fi; #F INSTALL_METHOD_FLAGS( , , , , , ) . ## BIND_GLOBAL( "INSTALL_METHOD_FLAGS", - function( opr, info, rel, flags, rank, method ) - local methods, narg, i, k, tmp, replace, match, j, lk; + function( opr, info, rel, flags, baserank, method ) + local methods, narg, i, k, tmp, replace, match, j, lk, rank; if IsHPCGAP then # TODO: once the GAP compiler supports 'atomic', use that @@ -152,6 +152,11 @@ BIND_GLOBAL( "INSTALL_METHOD_FLAGS", lk := WRITE_LOCK(METHODS_OPERATION_REGION); fi; # add the number of filters required for each argument + if IS_FUNCTION(baserank) then + rank := baserank(); + else + rank := baserank; + fi; if IS_CONSTRUCTOR(opr) then if 0 = LEN_LIST(flags) then Error(NAME_FUNC(opr),": constructors must have at least one argument"); @@ -262,6 +267,9 @@ BIND_GLOBAL( "INSTALL_METHOD_FLAGS", methods[i+(narg+4)] := IMMUTABLE_COPY_OBJ(info); if BASE_SIZE_METHODS_OPER_ENTRY >= 5 then methods[i+(narg+5)] := MakeImmutable([INPUT_FILENAME(), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER()]); + if BASE_SIZE_METHODS_OPER_ENTRY >= 6 then + methods[i+(narg+6)] := baserank; + fi; fi; # flush the cache @@ -290,9 +298,11 @@ end ); ## if supplied info should be a short but informative string ## that describes for what situation the method is installed, ## famp should be a function to be applied to the families -## of the arguments, -## and val should be an integer that measures the priority -## of the method. +## of the arguments. +## val should be an integer that measures the priority of the +## method, or a function of no arguments which should return such an +## integer and will be called each time method order is being +## recalculated (see ). ##

## The default values for info, famp, and val are ## the empty string, @@ -455,9 +465,11 @@ BIND_GLOBAL( "INSTALL_METHOD", # Check the rank. if not IsBound( arglist[ pos ] ) then Error( "the method is missing in " ); - elif IS_INT( arglist[ pos ] ) then - rank:= arglist[ pos ]; - pos:= pos + 1; + elif IS_INT( arglist[ pos ] ) or + (IS_FUNCTION( arglist[ pos ] ) and NARG_FUNC( arglist[ pos ] ) = 0 + and pos < LEN_LIST(arglist)) then + rank := arglist[ pos ]; + pos := pos+1; else rank:= 0; fi; diff --git a/lib/package.gi b/lib/package.gi index 34cb5b5b4d..44961eb8a6 100644 --- a/lib/package.gi +++ b/lib/package.gi @@ -1519,6 +1519,10 @@ InstallGlobalFunction( LoadPackage, function( arg ) return path; fi; + # Suspend reordering of methods following InstallTrueMethod + # because it would slow things down too much + SuspendMethodReordering(); + # Compute the order in which the packages are loaded. # For each set of packages with cyclic dependencies, # we will first read all `init.g' files @@ -1621,6 +1625,8 @@ InstallGlobalFunction( LoadPackage, function( arg ) LogPackageLoadingMessage( PACKAGE_DEBUG, "return from LoadPackage", Name ); GAPInfo.LoadPackageLevel:= GAPInfo.LoadPackageLevel - 1; + + ResumeMethodReordering(); return true; end ); @@ -1630,11 +1636,13 @@ InstallGlobalFunction( LoadPackage, function( arg ) #F LoadAllPackages() ## InstallGlobalFunction( LoadAllPackages, function() + SuspendMethodReordering(); if ValueOption( "reversed" ) = true then - List( Reversed( RecNames( GAPInfo.PackagesInfo ) ), LoadPackage ); + List( Reversed( RecNames( GAPInfo.PackagesInfo ) ), LoadPackage ); else - List( RecNames( GAPInfo.PackagesInfo ), LoadPackage ); - fi; + List( RecNames( GAPInfo.PackagesInfo ), LoadPackage ); + fi; + ResumeMethodReordering(); end ); diff --git a/src/c_oper1.c b/src/c_oper1.c index 813936c29f..531c12894a 100644 --- a/src/c_oper1.c +++ b/src/c_oper1.c @@ -1,7 +1,7 @@ #ifndef AVOID_PRECOMPILED /* C file produced by GAC */ #include "compiled.h" -#define FILE_CRC "70528668" +#define FILE_CRC "79494697" /* global variables used in handlers */ static GVar G_REREADING; @@ -603,7 +603,7 @@ static Obj HdlrFunc3 ( Obj a_info, Obj a_rel, Obj a_flags, - Obj a_rank, + Obj a_baserank, Obj a_method ) { Obj l_methods = 0; @@ -615,6 +615,7 @@ static Obj HdlrFunc3 ( Obj l_match = 0; Obj l_j = 0; Obj l_lk = 0; + Obj l_rank = 0; Obj t_1 = 0; Obj t_2 = 0; Obj t_3 = 0; @@ -632,6 +633,7 @@ static Obj HdlrFunc3 ( (void)l_match; (void)l_j; (void)l_lk; + (void)l_rank; Bag oldFrame; OLD_BRK_CURR_STAT @@ -640,6 +642,31 @@ static Obj HdlrFunc3 ( REM_BRK_CURR_STAT(); SET_BRK_CURR_STAT(0); + /* if IS_FUNCTION( baserank ) then */ + t_3 = GF_IS__FUNCTION; + t_2 = CALL_1ARGS( t_3, a_baserank ); + CHECK_FUNC_RESULT( t_2 ) + CHECK_BOOL( t_2 ) + t_1 = (Obj)(UInt)(t_2 != False); + if ( t_1 ) { + + /* rank := baserank( ); */ + CHECK_FUNC( a_baserank ) + t_1 = CALL_0ARGS( a_baserank ); + CHECK_FUNC_RESULT( t_1 ) + l_rank = t_1; + + } + + /* else */ + else { + + /* rank := baserank; */ + l_rank = a_baserank; + + } + /* fi */ + /* if IS_CONSTRUCTOR( opr ) then */ t_3 = GF_IS__CONSTRUCTOR; t_2 = CALL_1ARGS( t_3, a_opr ); @@ -671,8 +698,8 @@ static Obj HdlrFunc3 ( C_ELM_LIST_FPL( t_4, a_flags, INTOBJ_INT(1) ) t_2 = CALL_1ARGS( t_3, t_4 ); CHECK_FUNC_RESULT( t_2 ) - C_DIFF_FIA( t_1, a_rank, t_2 ) - a_rank = t_1; + C_DIFF_FIA( t_1, l_rank, t_2 ) + l_rank = t_1; } @@ -706,8 +733,8 @@ static Obj HdlrFunc3 ( t_7 = GF_RankFilter; t_6 = CALL_1ARGS( t_7, l_i ); CHECK_FUNC_RESULT( t_6 ) - C_SUM_FIA( t_5, a_rank, t_6 ) - a_rank = t_5; + C_SUM_FIA( t_5, l_rank, t_6 ) + l_rank = t_5; } /* od */ @@ -786,13 +813,13 @@ static Obj HdlrFunc3 ( C_SUM_FIA( t_5, l_i, t_6 ) CHECK_INT_POS( t_5 ) C_ELM_LIST_FPL( t_4, l_methods, t_5 ) - t_3 = (Obj)(UInt)(LT( a_rank, t_4 )); + t_3 = (Obj)(UInt)(LT( l_rank, t_4 )); t_1 = t_3; } if ( ! t_1 ) break; - /* i := i + (narg + 5); */ - C_SUM_FIA( t_2, l_narg, INTOBJ_INT(5) ) + /* i := i + (narg + 6); */ + C_SUM_FIA( t_2, l_narg, INTOBJ_INT(6) ) C_SUM_FIA( t_1, l_i, t_2 ) l_i = t_1; @@ -825,7 +852,7 @@ static Obj HdlrFunc3 ( C_SUM_FIA( t_5, t_6, INTOBJ_INT(3) ) CHECK_INT_POS( t_5 ) C_ELM_LIST_FPL( t_4, l_methods, t_5 ) - t_3 = (Obj)(UInt)(EQ( a_rank, t_4 )); + t_3 = (Obj)(UInt)(EQ( l_rank, t_4 )); t_1 = t_3; } if ( ! t_1 ) break; @@ -900,9 +927,9 @@ static Obj HdlrFunc3 ( } /* fi */ - /* k := k + narg + 5; */ + /* k := k + narg + 6; */ C_SUM_FIA( t_2, l_k, l_narg ) - C_SUM_FIA( t_1, t_2, INTOBJ_INT(5) ) + C_SUM_FIA( t_1, t_2, INTOBJ_INT(6) ) l_k = t_1; } @@ -925,7 +952,7 @@ static Obj HdlrFunc3 ( } if ( t_1 ) { - /* COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 5 + i + 1, 1, LEN_LIST( methods ) - i ); */ + /* COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 6 + i + 1, 1, LEN_LIST( methods ) - i ); */ t_1 = GF_COPY__LIST__ENTRIES; t_2 = NEW_PLIST( T_PLIST, 7 ); SET_LEN_PLIST( t_2, 7 ); @@ -937,7 +964,7 @@ static Obj HdlrFunc3 ( SET_ELM_PLIST( t_2, 3, INTOBJ_INT(1) ); SET_ELM_PLIST( t_2, 4, l_methods ); CHANGED_BAG( t_2 ); - C_SUM_FIA( t_5, l_narg, INTOBJ_INT(5) ) + C_SUM_FIA( t_5, l_narg, INTOBJ_INT(6) ) C_SUM_FIA( t_4, t_5, l_i ) C_SUM_FIA( t_3, t_4, INTOBJ_INT(1) ) SET_ELM_PLIST( t_2, 5, t_3 ); @@ -1203,7 +1230,7 @@ static Obj HdlrFunc3 ( C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(3) ) C_SUM_FIA( t_1, l_i, t_2 ) CHECK_INT_POS( t_1 ) - C_ASS_LIST_FPL( l_methods, t_1, a_rank ) + C_ASS_LIST_FPL( l_methods, t_1, l_rank ) /* methods[i + (narg + 4)] := IMMUTABLE_COPY_OBJ( info ); */ C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(4) ) @@ -1214,8 +1241,8 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_2 ) C_ASS_LIST_FPL( l_methods, t_1, t_2 ) - /* if 5 >= 5 then */ - t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(5)) >= ((Int)INTOBJ_INT(5))); + /* if 6 >= 5 then */ + t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(6)) >= ((Int)INTOBJ_INT(5))); if ( t_1 ) { /* methods[i + (narg + 5)] := MakeImmutable( [ INPUT_FILENAME( ), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER( ) ] ); */ @@ -1243,6 +1270,19 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_2 ) C_ASS_LIST_FPL( l_methods, t_1, t_2 ) + /* if 6 >= 6 then */ + t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(6)) >= ((Int)INTOBJ_INT(6))); + if ( t_1 ) { + + /* methods[i + (narg + 6)] := baserank; */ + C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(6) ) + C_SUM_FIA( t_1, l_i, t_2 ) + CHECK_INT_POS( t_1 ) + C_ASS_LIST_FPL( l_methods, t_1, a_baserank ) + + } + /* fi */ + } /* fi */ @@ -1735,14 +1775,41 @@ static Obj HdlrFunc6 ( } - /* elif IS_INT( arglist[pos] ) then */ + /* elif IS_INT( arglist[pos] ) or IS_FUNCTION( arglist[pos] ) and NARG_FUNC( arglist[pos] ) = 0 and pos < LEN_LIST( arglist ) then */ else { - t_3 = GF_IS__INT; - C_ELM_LIST_FPL( t_4, a_arglist, l_pos ) - t_2 = CALL_1ARGS( t_3, t_4 ); - CHECK_FUNC_RESULT( t_2 ) - CHECK_BOOL( t_2 ) - t_1 = (Obj)(UInt)(t_2 != False); + t_4 = GF_IS__INT; + C_ELM_LIST_FPL( t_5, a_arglist, l_pos ) + t_3 = CALL_1ARGS( t_4, t_5 ); + CHECK_FUNC_RESULT( t_3 ) + CHECK_BOOL( t_3 ) + t_2 = (Obj)(UInt)(t_3 != False); + t_1 = t_2; + if ( ! t_1 ) { + t_7 = GF_IS__FUNCTION; + C_ELM_LIST_FPL( t_8, a_arglist, l_pos ) + t_6 = CALL_1ARGS( t_7, t_8 ); + CHECK_FUNC_RESULT( t_6 ) + CHECK_BOOL( t_6 ) + t_5 = (Obj)(UInt)(t_6 != False); + t_4 = t_5; + if ( t_4 ) { + t_8 = GF_NARG__FUNC; + C_ELM_LIST_FPL( t_9, a_arglist, l_pos ) + t_7 = CALL_1ARGS( t_8, t_9 ); + CHECK_FUNC_RESULT( t_7 ) + t_6 = (Obj)(UInt)(EQ( t_7, INTOBJ_INT(0) )); + t_4 = t_6; + } + t_3 = t_4; + if ( t_3 ) { + t_7 = GF_LEN__LIST; + t_6 = CALL_1ARGS( t_7, a_arglist ); + CHECK_FUNC_RESULT( t_6 ) + t_5 = (Obj)(UInt)(LT( l_pos, t_6 )); + t_3 = t_5; + } + t_1 = t_3; + } if ( t_1 ) { /* rank := arglist[pos]; */ @@ -2703,8 +2770,8 @@ static Obj HdlrFunc7 ( t_6 = NewFunction( NameFunc[8], 1, 0, HdlrFunc8 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 652); - SET_ENDLINE_BODY(t_7, 670); + SET_STARTLINE_BODY(t_7, 664); + SET_ENDLINE_BODY(t_7, 682); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3307,8 +3374,8 @@ static Obj HdlrFunc11 ( t_1 = NewFunction( NameFunc[12], 1, 0, HdlrFunc12 ); SET_ENVI_FUNC( t_1, STATE(CurrLVars) ); t_2 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_2, 849); - SET_ENDLINE_BODY(t_2, 853); + SET_STARTLINE_BODY(t_2, 861); + SET_ENDLINE_BODY(t_2, 865); SET_FILENAME_BODY(t_2, FileName); SET_BODY_FUNC(t_1, t_2); CHANGED_BAG( STATE(CurrLVars) ); @@ -3387,8 +3454,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[13], 1, 0, HdlrFunc13 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 870); - SET_ENDLINE_BODY(t_7, 870); + SET_STARTLINE_BODY(t_7, 882); + SET_ENDLINE_BODY(t_7, 882); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3450,8 +3517,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[14], 2, 0, HdlrFunc14 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 892); - SET_ENDLINE_BODY(t_7, 915); + SET_STARTLINE_BODY(t_7, 904); + SET_ENDLINE_BODY(t_7, 927); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3499,8 +3566,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[15], 2, 0, HdlrFunc15 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 925); - SET_ENDLINE_BODY(t_7, 933); + SET_STARTLINE_BODY(t_7, 937); + SET_ENDLINE_BODY(t_7, 945); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3561,8 +3628,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[16], 3, 0, HdlrFunc16 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 942); - SET_ENDLINE_BODY(t_7, 955); + SET_STARTLINE_BODY(t_7, 954); + SET_ENDLINE_BODY(t_7, 967); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3935,8 +4002,8 @@ static Obj HdlrFunc17 ( t_4 = NewFunction( NameFunc[18], -1, 0, HdlrFunc18 ); SET_ENVI_FUNC( t_4, STATE(CurrLVars) ); t_5 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_5, 1021); - SET_ENDLINE_BODY(t_5, 1037); + SET_STARTLINE_BODY(t_5, 1033); + SET_ENDLINE_BODY(t_5, 1049); SET_FILENAME_BODY(t_5, FileName); SET_BODY_FUNC(t_4, t_5); CHANGED_BAG( STATE(CurrLVars) ); @@ -4044,9 +4111,14 @@ static Obj HdlrFunc1 ( CHANGED_BAG( STATE(CurrLVars) ); CALL_2ARGS( t_1, t_2, t_3 ); - /* BIND_GLOBAL( "INSTALL_METHOD_FLAGS", function ( opr, info, rel, flags, rank, method ) - local methods, narg, i, k, tmp, replace, match, j, lk; + /* BIND_GLOBAL( "INSTALL_METHOD_FLAGS", function ( opr, info, rel, flags, baserank, method ) + local methods, narg, i, k, tmp, replace, match, j, lk, rank; ; + if IS_FUNCTION( baserank ) then + rank := baserank( ); + else + rank := baserank; + fi; if IS_CONSTRUCTOR( opr ) then if 0 = LEN_LIST( flags ) then Error( NAME_FUNC( opr ), ": constructors must have at least one argument" ); @@ -4071,7 +4143,7 @@ static Obj HdlrFunc1 ( fi; i := 0; while i < LEN_LIST( methods ) and rank < methods[i + (narg + 3)] do - i := i + (narg + 5); + i := i + (narg + 6); od; replace := false; if REREADING then @@ -4088,11 +4160,11 @@ static Obj HdlrFunc1 ( break; fi; fi; - k := k + narg + 5; + k := k + narg + 6; od; fi; if not REREADING or not replace then - COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 5 + i + 1, 1, LEN_LIST( methods ) - i ); + COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 6 + i + 1, 1, LEN_LIST( methods ) - i ); fi; if rel = true then methods[i + 1] := RETURN_TRUE; @@ -4129,8 +4201,11 @@ static Obj HdlrFunc1 ( fi; methods[i + (narg + 3)] := rank; methods[i + (narg + 4)] := IMMUTABLE_COPY_OBJ( info ); - if 5 >= 5 then + if 6 >= 5 then methods[i + (narg + 5)] := MakeImmutable( [ INPUT_FILENAME( ), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER( ) ] ); + if 6 >= 6 then + methods[i + (narg + 6)] := baserank; + fi; fi; CHANGED_METHODS_OPERATION( opr, narg ); return; @@ -4141,7 +4216,7 @@ static Obj HdlrFunc1 ( SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); SET_STARTLINE_BODY(t_4, 146); - SET_ENDLINE_BODY(t_4, 274); + SET_ENDLINE_BODY(t_4, 282); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4156,8 +4231,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[4], -1, 0, HdlrFunc4 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 321); - SET_ENDLINE_BODY(t_4, 323); + SET_STARTLINE_BODY(t_4, 331); + SET_ENDLINE_BODY(t_4, 333); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4172,8 +4247,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[5], -1, 0, HdlrFunc5 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 348); - SET_ENDLINE_BODY(t_4, 350); + SET_STARTLINE_BODY(t_4, 358); + SET_ENDLINE_BODY(t_4, 360); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4247,7 +4322,7 @@ static Obj HdlrFunc1 ( od; if not IsBound( arglist[pos] ) then Error( "the method is missing in " ); - elif IS_INT( arglist[pos] ) then + elif IS_INT( arglist[pos] ) or IS_FUNCTION( arglist[pos] ) and NARG_FUNC( arglist[pos] ) = 0 and pos < LEN_LIST( arglist ) then rank := arglist[pos]; pos := pos + 1; else @@ -4342,17 +4417,17 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[6], 2, 0, HdlrFunc6 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 361); - SET_ENDLINE_BODY(t_4, 591); + SET_STARTLINE_BODY(t_4, 371); + SET_ENDLINE_BODY(t_4, 603); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); CALL_2ARGS( t_1, t_2, t_3 ); - /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (5 + 2); */ + /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (6 + 2); */ t_2 = GC_LENGTH__SETTER__METHODS__2; CHECK_BOUND( t_2, "LENGTH_SETTER_METHODS_2" ) - C_SUM_INTOBJS( t_3, INTOBJ_INT(5), INTOBJ_INT(2) ) + C_SUM_INTOBJS( t_3, INTOBJ_INT(6), INTOBJ_INT(2) ) C_SUM_FIA( t_1, t_2, t_3 ) AssGVar( G_LENGTH__SETTER__METHODS__2, t_1 ); @@ -4401,8 +4476,8 @@ static Obj HdlrFunc1 ( t_2 = NewFunction( NameFunc[7], 6, 0, HdlrFunc7 ); SET_ENVI_FUNC( t_2, STATE(CurrLVars) ); t_3 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_3, 610); - SET_ENDLINE_BODY(t_3, 674); + SET_STARTLINE_BODY(t_3, 622); + SET_ENDLINE_BODY(t_3, 686); SET_FILENAME_BODY(t_3, FileName); SET_BODY_FUNC(t_2, t_3); CHANGED_BAG( STATE(CurrLVars) ); @@ -4416,8 +4491,8 @@ static Obj HdlrFunc1 ( t_2 = NewFunction( NameFunc[9], 6, 0, HdlrFunc9 ); SET_ENVI_FUNC( t_2, STATE(CurrLVars) ); t_3 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_3, 677); - SET_ENDLINE_BODY(t_3, 683); + SET_STARTLINE_BODY(t_3, 689); + SET_ENDLINE_BODY(t_3, 695); SET_FILENAME_BODY(t_3, FileName); SET_BODY_FUNC(t_2, t_3); CHANGED_BAG( STATE(CurrLVars) ); @@ -4445,8 +4520,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[10], 2, 0, HdlrFunc10 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 696); - SET_ENDLINE_BODY(t_4, 720); + SET_STARTLINE_BODY(t_4, 708); + SET_ENDLINE_BODY(t_4, 732); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4530,8 +4605,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[11], 4, 0, HdlrFunc11 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 845); - SET_ENDLINE_BODY(t_4, 956); + SET_STARTLINE_BODY(t_4, 857); + SET_ENDLINE_BODY(t_4, 968); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4582,8 +4657,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[17], -1, 0, HdlrFunc17 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 991); - SET_ENDLINE_BODY(t_4, 1038); + SET_STARTLINE_BODY(t_4, 1003); + SET_ENDLINE_BODY(t_4, 1050); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4892,7 +4967,7 @@ static Int InitLibrary ( StructInitInfo * module ) static StructInitInfo module = { .type = MODULE_STATIC, .name = "GAPROOT/lib/oper1.g", - .crc = 70528668, + .crc = 79494697, .initKernel = InitKernel, .initLibrary = InitLibrary, .postRestore = PostRestore, diff --git a/src/c_type1.c b/src/c_type1.c index 79a54f9985..387f98010a 100644 --- a/src/c_type1.c +++ b/src/c_type1.c @@ -3320,10 +3320,10 @@ static Obj HdlrFunc1 ( CHANGED_BAG( STATE(CurrLVars) ); CALL_1ARGS( t_1, t_2 ); - /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (5 + 2); */ + /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (6 + 2); */ t_2 = GC_LENGTH__SETTER__METHODS__2; CHECK_BOUND( t_2, "LENGTH_SETTER_METHODS_2" ) - C_SUM_INTOBJS( t_3, INTOBJ_INT(5), INTOBJ_INT(2) ) + C_SUM_INTOBJS( t_3, INTOBJ_INT(6), INTOBJ_INT(2) ) C_SUM_FIA( t_1, t_2, t_3 ) AssGVar( G_LENGTH__SETTER__METHODS__2, t_1 ); diff --git a/src/hpc/c_oper1.c b/src/hpc/c_oper1.c index 2cfea3416a..c986073f60 100644 --- a/src/hpc/c_oper1.c +++ b/src/hpc/c_oper1.c @@ -1,7 +1,7 @@ #ifndef AVOID_PRECOMPILED /* C file produced by GAC */ #include "compiled.h" -#define FILE_CRC "70528668" +#define FILE_CRC "79494697" /* global variables used in handlers */ static GVar G_REREADING; @@ -619,7 +619,7 @@ static Obj HdlrFunc3 ( Obj a_info, Obj a_rel, Obj a_flags, - Obj a_rank, + Obj a_baserank, Obj a_method ) { Obj l_methods = 0; @@ -631,6 +631,7 @@ static Obj HdlrFunc3 ( Obj l_match = 0; Obj l_j = 0; Obj l_lk = 0; + Obj l_rank = 0; Obj t_1 = 0; Obj t_2 = 0; Obj t_3 = 0; @@ -648,6 +649,7 @@ static Obj HdlrFunc3 ( (void)l_match; (void)l_j; (void)l_lk; + (void)l_rank; Bag oldFrame; OLD_BRK_CURR_STAT @@ -664,6 +666,31 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_1 ) l_lk = t_1; + /* if IS_FUNCTION( baserank ) then */ + t_3 = GF_IS__FUNCTION; + t_2 = CALL_1ARGS( t_3, a_baserank ); + CHECK_FUNC_RESULT( t_2 ) + CHECK_BOOL( t_2 ) + t_1 = (Obj)(UInt)(t_2 != False); + if ( t_1 ) { + + /* rank := baserank( ); */ + CHECK_FUNC( a_baserank ) + t_1 = CALL_0ARGS( a_baserank ); + CHECK_FUNC_RESULT( t_1 ) + l_rank = t_1; + + } + + /* else */ + else { + + /* rank := baserank; */ + l_rank = a_baserank; + + } + /* fi */ + /* if IS_CONSTRUCTOR( opr ) then */ t_3 = GF_IS__CONSTRUCTOR; t_2 = CALL_1ARGS( t_3, a_opr ); @@ -695,8 +722,8 @@ static Obj HdlrFunc3 ( C_ELM_LIST_FPL( t_4, a_flags, INTOBJ_INT(1) ) t_2 = CALL_1ARGS( t_3, t_4 ); CHECK_FUNC_RESULT( t_2 ) - C_DIFF_FIA( t_1, a_rank, t_2 ) - a_rank = t_1; + C_DIFF_FIA( t_1, l_rank, t_2 ) + l_rank = t_1; } @@ -730,8 +757,8 @@ static Obj HdlrFunc3 ( t_7 = GF_RankFilter; t_6 = CALL_1ARGS( t_7, l_i ); CHECK_FUNC_RESULT( t_6 ) - C_SUM_FIA( t_5, a_rank, t_6 ) - a_rank = t_5; + C_SUM_FIA( t_5, l_rank, t_6 ) + l_rank = t_5; } /* od */ @@ -818,13 +845,13 @@ static Obj HdlrFunc3 ( C_SUM_FIA( t_5, l_i, t_6 ) CHECK_INT_POS( t_5 ) C_ELM_LIST_FPL( t_4, l_methods, t_5 ) - t_3 = (Obj)(UInt)(LT( a_rank, t_4 )); + t_3 = (Obj)(UInt)(LT( l_rank, t_4 )); t_1 = t_3; } if ( ! t_1 ) break; - /* i := i + (narg + 5); */ - C_SUM_FIA( t_2, l_narg, INTOBJ_INT(5) ) + /* i := i + (narg + 6); */ + C_SUM_FIA( t_2, l_narg, INTOBJ_INT(6) ) C_SUM_FIA( t_1, l_i, t_2 ) l_i = t_1; @@ -857,7 +884,7 @@ static Obj HdlrFunc3 ( C_SUM_FIA( t_5, t_6, INTOBJ_INT(3) ) CHECK_INT_POS( t_5 ) C_ELM_LIST_FPL( t_4, l_methods, t_5 ) - t_3 = (Obj)(UInt)(EQ( a_rank, t_4 )); + t_3 = (Obj)(UInt)(EQ( l_rank, t_4 )); t_1 = t_3; } if ( ! t_1 ) break; @@ -932,9 +959,9 @@ static Obj HdlrFunc3 ( } /* fi */ - /* k := k + narg + 5; */ + /* k := k + narg + 6; */ C_SUM_FIA( t_2, l_k, l_narg ) - C_SUM_FIA( t_1, t_2, INTOBJ_INT(5) ) + C_SUM_FIA( t_1, t_2, INTOBJ_INT(6) ) l_k = t_1; } @@ -957,7 +984,7 @@ static Obj HdlrFunc3 ( } if ( t_1 ) { - /* COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 5 + i + 1, 1, LEN_LIST( methods ) - i ); */ + /* COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 6 + i + 1, 1, LEN_LIST( methods ) - i ); */ t_1 = GF_COPY__LIST__ENTRIES; t_2 = NEW_PLIST( T_PLIST, 7 ); SET_LEN_PLIST( t_2, 7 ); @@ -969,7 +996,7 @@ static Obj HdlrFunc3 ( SET_ELM_PLIST( t_2, 3, INTOBJ_INT(1) ); SET_ELM_PLIST( t_2, 4, l_methods ); CHANGED_BAG( t_2 ); - C_SUM_FIA( t_5, l_narg, INTOBJ_INT(5) ) + C_SUM_FIA( t_5, l_narg, INTOBJ_INT(6) ) C_SUM_FIA( t_4, t_5, l_i ) C_SUM_FIA( t_3, t_4, INTOBJ_INT(1) ) SET_ELM_PLIST( t_2, 5, t_3 ); @@ -1235,7 +1262,7 @@ static Obj HdlrFunc3 ( C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(3) ) C_SUM_FIA( t_1, l_i, t_2 ) CHECK_INT_POS( t_1 ) - C_ASS_LIST_FPL( l_methods, t_1, a_rank ) + C_ASS_LIST_FPL( l_methods, t_1, l_rank ) /* methods[i + (narg + 4)] := IMMUTABLE_COPY_OBJ( info ); */ C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(4) ) @@ -1246,8 +1273,8 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_2 ) C_ASS_LIST_FPL( l_methods, t_1, t_2 ) - /* if 5 >= 5 then */ - t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(5)) >= ((Int)INTOBJ_INT(5))); + /* if 6 >= 5 then */ + t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(6)) >= ((Int)INTOBJ_INT(5))); if ( t_1 ) { /* methods[i + (narg + 5)] := MakeImmutable( [ INPUT_FILENAME( ), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER( ) ] ); */ @@ -1275,6 +1302,19 @@ static Obj HdlrFunc3 ( CHECK_FUNC_RESULT( t_2 ) C_ASS_LIST_FPL( l_methods, t_1, t_2 ) + /* if 6 >= 6 then */ + t_1 = (Obj)(UInt)(((Int)INTOBJ_INT(6)) >= ((Int)INTOBJ_INT(6))); + if ( t_1 ) { + + /* methods[i + (narg + 6)] := baserank; */ + C_SUM_INTOBJS( t_2, l_narg, INTOBJ_INT(6) ) + C_SUM_FIA( t_1, l_i, t_2 ) + CHECK_INT_POS( t_1 ) + C_ASS_LIST_FPL( l_methods, t_1, a_baserank ) + + } + /* fi */ + } /* fi */ @@ -1782,14 +1822,41 @@ static Obj HdlrFunc6 ( } - /* elif IS_INT( arglist[pos] ) then */ + /* elif IS_INT( arglist[pos] ) or IS_FUNCTION( arglist[pos] ) and NARG_FUNC( arglist[pos] ) = 0 and pos < LEN_LIST( arglist ) then */ else { - t_3 = GF_IS__INT; - C_ELM_LIST_FPL( t_4, a_arglist, l_pos ) - t_2 = CALL_1ARGS( t_3, t_4 ); - CHECK_FUNC_RESULT( t_2 ) - CHECK_BOOL( t_2 ) - t_1 = (Obj)(UInt)(t_2 != False); + t_4 = GF_IS__INT; + C_ELM_LIST_FPL( t_5, a_arglist, l_pos ) + t_3 = CALL_1ARGS( t_4, t_5 ); + CHECK_FUNC_RESULT( t_3 ) + CHECK_BOOL( t_3 ) + t_2 = (Obj)(UInt)(t_3 != False); + t_1 = t_2; + if ( ! t_1 ) { + t_7 = GF_IS__FUNCTION; + C_ELM_LIST_FPL( t_8, a_arglist, l_pos ) + t_6 = CALL_1ARGS( t_7, t_8 ); + CHECK_FUNC_RESULT( t_6 ) + CHECK_BOOL( t_6 ) + t_5 = (Obj)(UInt)(t_6 != False); + t_4 = t_5; + if ( t_4 ) { + t_8 = GF_NARG__FUNC; + C_ELM_LIST_FPL( t_9, a_arglist, l_pos ) + t_7 = CALL_1ARGS( t_8, t_9 ); + CHECK_FUNC_RESULT( t_7 ) + t_6 = (Obj)(UInt)(EQ( t_7, INTOBJ_INT(0) )); + t_4 = t_6; + } + t_3 = t_4; + if ( t_3 ) { + t_7 = GF_LEN__LIST; + t_6 = CALL_1ARGS( t_7, a_arglist ); + CHECK_FUNC_RESULT( t_6 ) + t_5 = (Obj)(UInt)(LT( l_pos, t_6 )); + t_3 = t_5; + } + t_1 = t_3; + } if ( t_1 ) { /* rank := arglist[pos]; */ @@ -2766,8 +2833,8 @@ static Obj HdlrFunc7 ( t_6 = NewFunction( NameFunc[8], 1, 0, HdlrFunc8 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 652); - SET_ENDLINE_BODY(t_7, 670); + SET_STARTLINE_BODY(t_7, 664); + SET_ENDLINE_BODY(t_7, 682); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3370,8 +3437,8 @@ static Obj HdlrFunc11 ( t_1 = NewFunction( NameFunc[12], 1, 0, HdlrFunc12 ); SET_ENVI_FUNC( t_1, STATE(CurrLVars) ); t_2 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_2, 849); - SET_ENDLINE_BODY(t_2, 853); + SET_STARTLINE_BODY(t_2, 861); + SET_ENDLINE_BODY(t_2, 865); SET_FILENAME_BODY(t_2, FileName); SET_BODY_FUNC(t_1, t_2); CHANGED_BAG( STATE(CurrLVars) ); @@ -3450,8 +3517,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[13], 1, 0, HdlrFunc13 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 870); - SET_ENDLINE_BODY(t_7, 870); + SET_STARTLINE_BODY(t_7, 882); + SET_ENDLINE_BODY(t_7, 882); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3525,8 +3592,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[14], 2, 0, HdlrFunc14 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 892); - SET_ENDLINE_BODY(t_7, 915); + SET_STARTLINE_BODY(t_7, 904); + SET_ENDLINE_BODY(t_7, 927); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3574,8 +3641,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[15], 2, 0, HdlrFunc15 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 925); - SET_ENDLINE_BODY(t_7, 933); + SET_STARTLINE_BODY(t_7, 937); + SET_ENDLINE_BODY(t_7, 945); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -3636,8 +3703,8 @@ static Obj HdlrFunc11 ( t_6 = NewFunction( NameFunc[16], 3, 0, HdlrFunc16 ); SET_ENVI_FUNC( t_6, STATE(CurrLVars) ); t_7 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_7, 942); - SET_ENDLINE_BODY(t_7, 955); + SET_STARTLINE_BODY(t_7, 954); + SET_ENDLINE_BODY(t_7, 967); SET_FILENAME_BODY(t_7, FileName); SET_BODY_FUNC(t_6, t_7); CHANGED_BAG( STATE(CurrLVars) ); @@ -4010,8 +4077,8 @@ static Obj HdlrFunc17 ( t_4 = NewFunction( NameFunc[18], -1, 0, HdlrFunc18 ); SET_ENVI_FUNC( t_4, STATE(CurrLVars) ); t_5 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_5, 1021); - SET_ENDLINE_BODY(t_5, 1037); + SET_STARTLINE_BODY(t_5, 1033); + SET_ENDLINE_BODY(t_5, 1049); SET_FILENAME_BODY(t_5, FileName); SET_BODY_FUNC(t_4, t_5); CHANGED_BAG( STATE(CurrLVars) ); @@ -4128,9 +4195,14 @@ static Obj HdlrFunc1 ( CHECK_FUNC_RESULT( t_3 ) CALL_2ARGS( t_1, t_2, t_3 ); - /* BIND_GLOBAL( "INSTALL_METHOD_FLAGS", function ( opr, info, rel, flags, rank, method ) - local methods, narg, i, k, tmp, replace, match, j, lk; + /* BIND_GLOBAL( "INSTALL_METHOD_FLAGS", function ( opr, info, rel, flags, baserank, method ) + local methods, narg, i, k, tmp, replace, match, j, lk, rank; lk := WRITE_LOCK( METHODS_OPERATION_REGION ); + if IS_FUNCTION( baserank ) then + rank := baserank( ); + else + rank := baserank; + fi; if IS_CONSTRUCTOR( opr ) then if 0 = LEN_LIST( flags ) then Error( NAME_FUNC( opr ), ": constructors must have at least one argument" ); @@ -4155,7 +4227,7 @@ static Obj HdlrFunc1 ( fi; i := 0; while i < LEN_LIST( methods ) and rank < methods[i + (narg + 3)] do - i := i + (narg + 5); + i := i + (narg + 6); od; replace := false; if REREADING then @@ -4172,11 +4244,11 @@ static Obj HdlrFunc1 ( break; fi; fi; - k := k + narg + 5; + k := k + narg + 6; od; fi; if not REREADING or not replace then - COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 5 + i + 1, 1, LEN_LIST( methods ) - i ); + COPY_LIST_ENTRIES( methods, i + 1, 1, methods, narg + 6 + i + 1, 1, LEN_LIST( methods ) - i ); fi; if rel = true then methods[i + 1] := RETURN_TRUE; @@ -4213,8 +4285,11 @@ static Obj HdlrFunc1 ( fi; methods[i + (narg + 3)] := rank; methods[i + (narg + 4)] := IMMUTABLE_COPY_OBJ( info ); - if 5 >= 5 then + if 6 >= 5 then methods[i + (narg + 5)] := MakeImmutable( [ INPUT_FILENAME( ), READEVALCOMMAND_LINENUMBER, INPUT_LINENUMBER( ) ] ); + if 6 >= 6 then + methods[i + (narg + 6)] := baserank; + fi; fi; SET_METHODS_OPERATION( opr, narg, MakeReadOnlySingleObj( methods ) ); UNLOCK( lk ); @@ -4226,7 +4301,7 @@ static Obj HdlrFunc1 ( SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); SET_STARTLINE_BODY(t_4, 146); - SET_ENDLINE_BODY(t_4, 274); + SET_ENDLINE_BODY(t_4, 282); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4241,8 +4316,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[4], -1, 0, HdlrFunc4 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 321); - SET_ENDLINE_BODY(t_4, 323); + SET_STARTLINE_BODY(t_4, 331); + SET_ENDLINE_BODY(t_4, 333); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4257,8 +4332,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[5], -1, 0, HdlrFunc5 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 348); - SET_ENDLINE_BODY(t_4, 350); + SET_STARTLINE_BODY(t_4, 358); + SET_ENDLINE_BODY(t_4, 360); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4332,7 +4407,7 @@ static Obj HdlrFunc1 ( od; if not IsBound( arglist[pos] ) then Error( "the method is missing in " ); - elif IS_INT( arglist[pos] ) then + elif IS_INT( arglist[pos] ) or IS_FUNCTION( arglist[pos] ) and NARG_FUNC( arglist[pos] ) = 0 and pos < LEN_LIST( arglist ) then rank := arglist[pos]; pos := pos + 1; else @@ -4427,17 +4502,17 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[6], 2, 0, HdlrFunc6 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 361); - SET_ENDLINE_BODY(t_4, 591); + SET_STARTLINE_BODY(t_4, 371); + SET_ENDLINE_BODY(t_4, 603); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); CALL_2ARGS( t_1, t_2, t_3 ); - /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (5 + 2); */ + /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (6 + 2); */ t_2 = GC_LENGTH__SETTER__METHODS__2; CHECK_BOUND( t_2, "LENGTH_SETTER_METHODS_2" ) - C_SUM_INTOBJS( t_3, INTOBJ_INT(5), INTOBJ_INT(2) ) + C_SUM_INTOBJS( t_3, INTOBJ_INT(6), INTOBJ_INT(2) ) C_SUM_FIA( t_1, t_2, t_3 ) AssGVar( G_LENGTH__SETTER__METHODS__2, t_1 ); @@ -4486,8 +4561,8 @@ static Obj HdlrFunc1 ( t_2 = NewFunction( NameFunc[7], 6, 0, HdlrFunc7 ); SET_ENVI_FUNC( t_2, STATE(CurrLVars) ); t_3 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_3, 610); - SET_ENDLINE_BODY(t_3, 674); + SET_STARTLINE_BODY(t_3, 622); + SET_ENDLINE_BODY(t_3, 686); SET_FILENAME_BODY(t_3, FileName); SET_BODY_FUNC(t_2, t_3); CHANGED_BAG( STATE(CurrLVars) ); @@ -4501,8 +4576,8 @@ static Obj HdlrFunc1 ( t_2 = NewFunction( NameFunc[9], 6, 0, HdlrFunc9 ); SET_ENVI_FUNC( t_2, STATE(CurrLVars) ); t_3 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_3, 677); - SET_ENDLINE_BODY(t_3, 683); + SET_STARTLINE_BODY(t_3, 689); + SET_ENDLINE_BODY(t_3, 695); SET_FILENAME_BODY(t_3, FileName); SET_BODY_FUNC(t_2, t_3); CHANGED_BAG( STATE(CurrLVars) ); @@ -4530,8 +4605,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[10], 2, 0, HdlrFunc10 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 696); - SET_ENDLINE_BODY(t_4, 720); + SET_STARTLINE_BODY(t_4, 708); + SET_ENDLINE_BODY(t_4, 732); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4615,8 +4690,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[11], 4, 0, HdlrFunc11 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 845); - SET_ENDLINE_BODY(t_4, 956); + SET_STARTLINE_BODY(t_4, 857); + SET_ENDLINE_BODY(t_4, 968); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4667,8 +4742,8 @@ static Obj HdlrFunc1 ( t_3 = NewFunction( NameFunc[17], -1, 0, HdlrFunc17 ); SET_ENVI_FUNC( t_3, STATE(CurrLVars) ); t_4 = NewBag( T_BODY, sizeof(BodyHeader) ); - SET_STARTLINE_BODY(t_4, 991); - SET_ENDLINE_BODY(t_4, 1038); + SET_STARTLINE_BODY(t_4, 1003); + SET_ENDLINE_BODY(t_4, 1050); SET_FILENAME_BODY(t_4, FileName); SET_BODY_FUNC(t_3, t_4); CHANGED_BAG( STATE(CurrLVars) ); @@ -4993,7 +5068,7 @@ static Int InitLibrary ( StructInitInfo * module ) static StructInitInfo module = { .type = MODULE_STATIC, .name = "GAPROOT/lib/oper1.g", - .crc = 70528668, + .crc = 79494697, .initKernel = InitKernel, .initLibrary = InitLibrary, .postRestore = PostRestore, diff --git a/src/hpc/c_type1.c b/src/hpc/c_type1.c index a8a53ea27f..d184cab36d 100644 --- a/src/hpc/c_type1.c +++ b/src/hpc/c_type1.c @@ -3550,10 +3550,10 @@ static Obj HdlrFunc1 ( CHANGED_BAG( STATE(CurrLVars) ); CALL_1ARGS( t_1, t_2 ); - /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (5 + 2); */ + /* LENGTH_SETTER_METHODS_2 := LENGTH_SETTER_METHODS_2 + (6 + 2); */ t_2 = GC_LENGTH__SETTER__METHODS__2; CHECK_BOUND( t_2, "LENGTH_SETTER_METHODS_2" ) - C_SUM_INTOBJS( t_3, INTOBJ_INT(5), INTOBJ_INT(2) ) + C_SUM_INTOBJS( t_3, INTOBJ_INT(6), INTOBJ_INT(2) ) C_SUM_FIA( t_1, t_2, t_3 ) AssGVar( G_LENGTH__SETTER__METHODS__2, t_1 ); diff --git a/src/opers.c b/src/opers.c index d0b1dcff57..16a64df1d9 100644 --- a/src/opers.c +++ b/src/opers.c @@ -669,7 +669,7 @@ Obj FuncAND_FLAGS ( Obj HIDDEN_IMPS; Obj WITH_HIDDEN_IMPS_FLAGS_CACHE; -enum { HIDDEN_IMPS_CACHE_LENGTH = 2003 }; +enum { HIDDEN_IMPS_CACHE_LENGTH = 20003 }; /* Forward declaration of FuncFLAGS_FILTER */ Obj FuncFLAGS_FILTER(Obj self, Obj oper); @@ -829,7 +829,7 @@ Obj FuncWITH_HIDDEN_IMPS_FLAGS(Obj self, Obj flags) static Obj IMPLICATIONS_SIMPLE; static Obj IMPLICATIONS_COMPOSED; static Obj WITH_IMPS_FLAGS_CACHE; -enum { IMPS_CACHE_LENGTH = 11001 }; +enum { IMPS_CACHE_LENGTH = 21001 }; /**************************************************************************** ** @@ -1912,7 +1912,7 @@ static Obj NEXT_VMETHOD_PRINT_INFO; // Use of 'ALWAYS_INLINE' is critical for performance, see discussion // earlier in this file. enum { - BASE_SIZE_METHODS_OPER_ENTRY = 5, + BASE_SIZE_METHODS_OPER_ENTRY = 6, }; static ALWAYS_INLINE Obj GetMethodUncached( UInt verbose, UInt constructor, UInt n, Obj methods, Int prec, Obj types[]) @@ -1931,6 +1931,9 @@ static ALWAYS_INLINE Obj GetMethodUncached( // entry n+3 is the rank // entry n+4 is the info text // entry n+5 is, if set, the location where the method was installed + // entry n+6 is, if set, the relative rank that was supplied when + // the method was installed, either as a small integer + // or a function of no arguments // check argument filters against the given types Obj filter; diff --git a/tst/testinstall/method-rankfns.tst b/tst/testinstall/method-rankfns.tst new file mode 100644 index 0000000000..36d101ca2c --- /dev/null +++ b/tst/testinstall/method-rankfns.tst @@ -0,0 +1,21 @@ +gap> START_TEST("method-rankfns.tst"); +gap> myOp := NewOperation("myOp",[IsObject]);; +gap> myC := NewConstructor("myC",[IsObject]);; +gap> xxx := 1;; +gap> InstallMethod(myOp,"method1",[IsObject],x->1); +gap> InstallMethod(myOp,"method2",[IsObject],{}->xxx,x->2); +gap> InstallMethod(myC,"cons1",[IsObject],x->1); +gap> InstallMethod(myC,"cons2",[IsObject],{}->xxx,x->2); +gap> myOp(3); +2 +gap> myC(IsObject); +2 +gap> xxx := -1;; +gap> RECALCULATE_ALL_METHOD_RANKS(); +gap> myOp(3); +1 +gap> myC(IsObject); +1 +gap> Unbind(myOp); +gap> Unbind(myC); +gap> STOP_TEST("method-rankfns.tst"); diff --git a/tst/testinstall/method-reordering.tst b/tst/testinstall/method-reordering.tst new file mode 100644 index 0000000000..bbaa97c0ed --- /dev/null +++ b/tst/testinstall/method-reordering.tst @@ -0,0 +1,35 @@ +gap> START_TEST("method-reordering.tst"); +gap> CheckReorder := function(explicit) +> local f1, f2, f3, myOp, fam, t, o, o2, myC; +> f1 := NewFilter("filter1",100); +> f2 := NewFilter("filter1",10); +> f3 := NewFilter("filter1",1); +> myOp := NewOperation("myOp", [IsObject]); +> myC := NewConstructor("myC", [IsObject]); +> InstallMethod(myOp, "meth1", [f2], x ->1); +> InstallMethod(myOp, "meth2", [f3], x ->2); +> fam := NewFamily("myFam"); +> t := NewType(fam, IsComponentObjectRep and f2 and f3); +> o := Objectify(t, rec()); +> o2 := Objectify(t, rec()); +> InstallMethod(myC, "cons1", [f2], x ->o); +> InstallMethod(myC, "cons2", [f3], x ->o2); +> if myOp(o) <> 1 or not IsIdenticalObj(myC(IsObject),o2) then +> Error("Initial method selection wrong"); +> fi; +> InstallTrueMethod(f1,f3); +> if explicit then +> RECALCULATE_ALL_METHOD_RANKS(); +> fi; +> return IsIdenticalObj(myC(IsObject),o) and myOp(o) = 2; +> end;; +gap> CheckReorder(false); +true +gap> SuspendMethodReordering(); +gap> CheckReorder(false); +false +gap> CheckReorder(true); +true +gap> ResumeMethodReordering(); +gap> Unbind(CheckReorder); +gap> STOP_TEST("method-reordering.tst"); diff --git a/tst/testinstall/triviso.tst b/tst/testinstall/triviso.tst index 5776ddfa3c..5b7bacb792 100644 --- a/tst/testinstall/triviso.tst +++ b/tst/testinstall/triviso.tst @@ -9,11 +9,11 @@ gap> START_TEST("triviso.tst"); gap> G := Group(()); Group(()) gap> phi := IsomorphismPermGroup(G); -[ ] -> [ ] +IdentityMapping( Group(()) ) gap> HasIsBijective(phi); true gap> inv := InverseGeneralMapping(phi); -[ ] -> [ ] +IdentityMapping( Group(()) ) gap> HasIsMapping(inv); true gap> STOP_TEST( "triviso.tst", 1); diff --git a/tst/testinstall/varargs.tst b/tst/testinstall/varargs.tst index f31c64b2ac..52a749bdc3 100644 --- a/tst/testinstall/varargs.tst +++ b/tst/testinstall/varargs.tst @@ -87,7 +87,7 @@ function ( <>, <>, <>, <>, <>, <> ) end gap> Display(InstallMethod); function ( <>... ) - <> + <> end gap> [1..2]; [ 1, 2 ]