mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-24 10:09:33 +02:00
* Make tglobalstat a class
This commit is contained in:
parent
6f7481fd24
commit
1351746a46
@ -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 }
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user