* Make tglobalstat a class

This commit is contained in:
Michaël Van Canneyt 2024-02-01 10:50:37 +01:00 committed by Michael Van Canneyt
parent 6f7481fd24
commit 1351746a46
4 changed files with 186 additions and 100 deletions

View File

@ -225,7 +225,7 @@ interface
waitingunits: tfpobjectlist; waitingunits: tfpobjectlist;
finishstate: pointer; finishstate: pointer;
globalstate: pointer; globalstate: tobject;
namespace: pshortstring; { for JVM target: corresponds to Java package name } namespace: pshortstring; { for JVM target: corresponds to Java package name }

View File

@ -37,8 +37,8 @@ uses
type type
pglobalstate=^tglobalstate;
tglobalstate=record tglobalstate = class
{ scanner } { scanner }
oldidtoken, oldidtoken,
oldtoken : ttoken; oldtoken : ttoken;
@ -67,95 +67,184 @@ type
old_debuginfo : tdebuginfo; old_debuginfo : tdebuginfo;
old_scanner : tscannerfile; old_scanner : tscannerfile;
old_parser_file : string; old_parser_file : string;
constructor create(savefull : boolean);
destructor destroy; override;
procedure clearscanner;
class procedure remove_scanner_from_states(scanner : tscannerfile); static;
procedure save(full : boolean);
procedure restore(full : boolean);
end; end;
procedure save_global_state(out state:tglobalstate;full:boolean); procedure save_global_state(state:tglobalstate;full:boolean);
procedure restore_global_state(const state:tglobalstate;full:boolean); procedure restore_global_state(state:tglobalstate;full:boolean);
implementation implementation
uses uses
pbase,comphook; pbase,comphook;
procedure save_global_state(out state:tglobalstate;full:boolean); var
states : array of tglobalstate;
statecount : integer = 0;
class procedure tglobalstate.remove_scanner_from_states(scanner : tscannerfile);
var
i : integer;
begin
for I:=0 to statecount-1 do
if (states[i].old_scanner=scanner) then
states[i].clearscanner;
end;
procedure addstate(astate : tglobalstate);
var
l : integer;
begin
l:=length(states);
if l=statecount then
setlength(states,l+10);
states[statecount]:=astate;
inc(statecount);
end;
procedure removestate(astate : tglobalstate);
var
l : integer;
begin
l:=statecount-1;
While (l>=0) and (states[l]<>astate) do
dec(l);
if l<0 then
exit;
if l<>statecount-1 then
states[l]:=states[statecount-1];
states[statecount-1]:=Nil;
Dec(Statecount);
end;
procedure save_global_state(state:tglobalstate;full:boolean);
begin begin
with state do state.save(full);
end;
procedure restore_global_state(state:tglobalstate;full:boolean);
begin
state.restore(full);
end;
procedure tglobalstate.save(full: boolean);
begin
old_current_module:=current_module;
{ save symtable state }
oldsymtablestack:=symtablestack;
oldmacrosymtablestack:=macrosymtablestack;
oldcurrent_procinfo:=current_procinfo;
{ save scanner state }
oldc:=c;
oldpattern:=pattern;
oldorgpattern:=orgpattern;
oldtoken:=token;
oldidtoken:=idtoken;
old_block_type:=block_type;
oldtokenpos:=current_tokenpos;
old_switchesstatestack:=switchesstatestack;
old_switchesstatestackpos:=switchesstatestackpos;
{ save cg }
oldparse_only:=parse_only;
{ save akt... state }
{ handle the postponed case first }
//flushpendingswitchesstate;
oldcurrent_filepos:=current_filepos;
old_settings:=current_settings;
old_verbosity:=status.verbosity;
if full then
begin begin
old_current_module:=current_module; old_asmdata:=current_asmdata;
old_debuginfo:=current_debuginfo;
{ save symtable state } old_parser_file:=parser_current_file;
oldsymtablestack:=symtablestack; old_scanner:=current_scanner;
oldmacrosymtablestack:=macrosymtablestack;
oldcurrent_procinfo:=current_procinfo;
{ save scanner state }
oldc:=c;
oldpattern:=pattern;
oldorgpattern:=orgpattern;
oldtoken:=token;
oldidtoken:=idtoken;
old_block_type:=block_type;
oldtokenpos:=current_tokenpos;
old_switchesstatestack:=switchesstatestack;
old_switchesstatestackpos:=switchesstatestackpos;
{ save cg }
oldparse_only:=parse_only;
{ save akt... state }
{ handle the postponed case first }
//flushpendingswitchesstate;
oldcurrent_filepos:=current_filepos;
old_settings:=current_settings;
old_verbosity:=status.verbosity;
if full then
begin
old_asmdata:=current_asmdata;
old_debuginfo:=current_debuginfo;
old_parser_file:=parser_current_file;
old_scanner:=current_scanner;
end;
end; end;
end; end;
procedure tglobalstate.restore(full: boolean);
procedure restore_global_state(const state:tglobalstate;full:boolean);
begin begin
with state do { restore scanner }
c:=oldc;
pattern:=oldpattern;
orgpattern:=oldorgpattern;
token:=oldtoken;
idtoken:=oldidtoken;
current_tokenpos:=oldtokenpos;
block_type:=old_block_type;
switchesstatestack:=old_switchesstatestack;
switchesstatestackpos:=old_switchesstatestackpos;
{ restore cg }
parse_only:=oldparse_only;
{ restore symtable state }
symtablestack:=oldsymtablestack;
macrosymtablestack:=oldmacrosymtablestack;
current_procinfo:=oldcurrent_procinfo;
current_filepos:=oldcurrent_filepos;
current_settings:=old_settings;
status.verbosity:=old_verbosity;
if full then
begin begin
{ restore scanner } set_current_module(old_current_module);
c:=oldc; // These can be different
pattern:=oldpattern; current_asmdata:=old_asmdata;
orgpattern:=oldorgpattern; current_debuginfo:=old_debuginfo;
token:=oldtoken;
idtoken:=oldidtoken;
current_tokenpos:=oldtokenpos;
block_type:=old_block_type;
switchesstatestack:=old_switchesstatestack;
switchesstatestackpos:=old_switchesstatestackpos;
{ restore cg }
parse_only:=oldparse_only;
{ restore symtable state }
symtablestack:=oldsymtablestack;
macrosymtablestack:=oldmacrosymtablestack;
current_procinfo:=oldcurrent_procinfo;
current_filepos:=oldcurrent_filepos;
current_settings:=old_settings;
status.verbosity:=old_verbosity;
if full then
begin
current_module:=old_current_module; {!}
current_asmdata:=old_asmdata;
current_debuginfo:=old_debuginfo;
set_current_scanner(old_scanner);
parser_current_file:=old_parser_file;
end;
end; end;
end; end;
constructor tglobalstate.create(savefull: boolean);
begin
addstate(self);
save(savefull);
end;
destructor tglobalstate.destroy;
begin
removestate(self);
inherited destroy;
end;
procedure tglobalstate.clearscanner;
begin
old_scanner:=nil;
oldidtoken:=NOTOKEN;
oldtoken:=NOTOKEN;
oldtokenpos:=Default(tfileposinfo);
oldc:=#0;
oldpattern:='';
oldorgpattern:='';
old_block_type:=bt_none;
end;
initialization
onfreescanner:=@tglobalstate.remove_scanner_from_states;
finalization
onfreescanner:=Nil;
end. end.

View File

@ -336,7 +336,7 @@ implementation
procedure compile_module(module : tmodule); procedure compile_module(module : tmodule);
var var
olddata : pglobalstate; olddata : tglobalstate;
hp,hp2 : tmodule; hp,hp2 : tmodule;
finished : boolean; finished : boolean;
sc : tscannerfile; sc : tscannerfile;
@ -352,10 +352,9 @@ implementation
{ Uses heap memory instead of placing everything on the { Uses heap memory instead of placing everything on the
stack. This is needed because compile() can be called stack. This is needed because compile() can be called
recursively } recursively }
new(olddata);
{ handle the postponed case first } { handle the postponed case first }
flushpendingswitchesstate; flushpendingswitchesstate;
save_global_state(olddata^,false); olddata:=tglobalstate.create(false);
{ reset parser, a previous fatal error could have left these variables in an unreliable state, this is { reset parser, a previous fatal error could have left these variables in an unreliable state, this is
important for the IDE } important for the IDE }
@ -478,7 +477,7 @@ implementation
{ Write Browser Collections } { Write Browser Collections }
do_extractsymbolinfo; do_extractsymbolinfo;
restore_global_state(olddata^,false); olddata.restore(false);
{ Restore all locally modified warning messages } { Restore all locally modified warning messages }
RestoreLocalVerbosity(current_settings.pmessage); RestoreLocalVerbosity(current_settings.pmessage);
@ -523,12 +522,12 @@ implementation
file which will result in pointing to the wrong position in the file which will result in pointing to the wrong position in the
file. In the normal case current_scanner and current_module.scanner file. In the normal case current_scanner and current_module.scanner
would be Nil, thus nothing bad would happen } would be Nil, thus nothing bad would happen }
if olddata^.old_current_module<>current_module then if olddata.old_current_module<>current_module then
set_current_module(olddata^.old_current_module); set_current_module(olddata.old_current_module);
FreeLocalVerbosity(current_settings.pmessage); FreeLocalVerbosity(current_settings.pmessage);
dispose(olddata); FreeAndNil(olddata);
end; end;
end; end;

View File

@ -295,7 +295,7 @@ implementation
procedure loadsystemunit(curr : tmodule); procedure loadsystemunit(curr : tmodule);
var var
state: pglobalstate; state: tglobalstate;
begin begin
{ we are going to rebuild the symtablestack, clear it first } { we are going to rebuild the symtablestack, clear it first }
@ -326,11 +326,10 @@ implementation
{ load_intern_types resets the scanner... } { load_intern_types resets the scanner... }
current_scanner.tempcloseinputfile; current_scanner.tempcloseinputfile;
new(state); state:=tglobalstate.create(true);
save_global_state(state^,true);
load_intern_types; load_intern_types;
restore_global_state(state^,true); state.restore(true);
dispose(state); FreeAndNil(state);
current_scanner.tempopeninputfile; current_scanner.tempopeninputfile;
{ Set the owner of errorsym and errortype to symtable to { Set the owner of errorsym and errortype to symtable to
@ -572,33 +571,31 @@ implementation
until false; until false;
end; end;
procedure loadunits(curr: tmodule; preservest:tsymtable); procedure loadunits(curr: tmodule; preservest:tsymtable);
var var
s,sorg : ansistring; s,sorg : ansistring;
pu,pu2 : tused_unit; pu,pu2 : tused_unit;
hp2 : tmodule; hp2 : tmodule;
state: pglobalstate; state: tglobalstate;
procedure restorestate; procedure restorestate;
begin begin
restore_global_state(state^,true); state.restore(true);
if assigned(current_scanner) and (current_module.scanner=current_scanner) then if assigned(current_scanner) and (current_module.scanner=current_scanner) then
begin begin
if assigned(current_scanner.inputfile) then if assigned(current_scanner.inputfile) then
current_scanner.tempopeninputfile; current_scanner.tempopeninputfile;
end; end;
dispose(state); state.free;
end; end;
begin begin
parseusesclause(curr); parseusesclause(curr);
current_scanner.tempcloseinputfile; current_scanner.tempcloseinputfile;
new(state); state:=tglobalstate.create(true);
save_global_state(state^,true);
{ Load the units } { Load the units }
pu:=tused_unit(curr.used_units.first); pu:=tused_unit(curr.used_units.first);
while assigned(pu) do while assigned(pu) do
@ -949,7 +946,7 @@ type
finalize_procinfo : tcgprocinfo; finalize_procinfo : tcgprocinfo;
i,j : integer; i,j : integer;
finishstate:pfinishstate; finishstate:pfinishstate;
globalstate:pglobalstate; globalstate:tglobalstate;
begin begin
result:=true; result:=true;
@ -1014,9 +1011,7 @@ type
begin begin
{ save the current state, so the parsing can continue where we left { save the current state, so the parsing can continue where we left
of here } of here }
New(globalstate); globalstate:=tglobalstate.create(true);
save_global_state(globalstate^,true);
curr.globalstate:=globalstate;
end; end;
end; end;
@ -1086,7 +1081,6 @@ type
{ Insert _GLOBAL_OFFSET_TABLE_ symbol if system uses it } { Insert _GLOBAL_OFFSET_TABLE_ symbol if system uses it }
maybe_load_got; maybe_load_got;
if not curr.interface_only then if not curr.interface_only then
begin begin
consume(_IMPLEMENTATION); consume(_IMPLEMENTATION);
@ -1259,10 +1253,12 @@ type
{ consume the semicolon after maps have been updated else conditional compiling expressions { consume the semicolon after maps have been updated else conditional compiling expressions
might cause internal errors, see tw8611 } might cause internal errors, see tw8611 }
if consume_semicolon_after_uses then if consume_semicolon_after_uses then
consume(_SEMICOLON); consume(_SEMICOLON);
result:=parse_unit_interface_declarations(curr); result:=parse_unit_interface_declarations(curr);
end; end;
procedure finish_unit(module:tmodule;immediate:boolean); procedure finish_unit(module:tmodule;immediate:boolean);
@ -1285,8 +1281,8 @@ type
procedure module_is_done(curr: tmodule);inline; procedure module_is_done(curr: tmodule);inline;
begin begin
dispose(pglobalstate(curr.globalstate));
curr.globalstate:=nil; FreeAndNil(curr.globalstate);
dispose(pfinishstate(curr.finishstate)); dispose(pfinishstate(curr.finishstate));
curr.finishstate:=nil; curr.finishstate:=nil;
end; end;
@ -1316,7 +1312,7 @@ type
save_global_state(globalstate,true); save_global_state(globalstate,true);
if not assigned(module.globalstate) then if not assigned(module.globalstate) then
internalerror(2012091802); internalerror(2012091802);
restore_global_state(pglobalstate(module.globalstate)^,true); tglobalstate(module.globalstate).restore(true);
end; end;
{ curr is now module } { curr is now module }
@ -1604,6 +1600,8 @@ type
Message1(unit_u_finished_compiling,module.modulename^); Message1(unit_u_finished_compiling,module.modulename^);
module_is_done(module); module_is_done(module);
module.end_of_parsing;
if not immediate then if not immediate then
restore_global_state(globalstate,true); restore_global_state(globalstate,true);