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 ]