mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 06:45:58 +02:00
* keep track of the number of abstract methods per class via a counter
* use this counter to mark classes containing abstract methods as "abstract" in the bytecode per the JVM spec * also use the counter to short-circuit printing of all abstract methods in a class when creating a new instance (we build the list of abstract methods every time a new instance is created, which is a waste of time if there are none in the first place) git-svn-id: branches/jvmbackend@18635 -
This commit is contained in:
parent
92fbbcff88
commit
6154f1b0d9
@ -570,7 +570,8 @@ implementation
|
||||
AsmWrite('.class ');
|
||||
if oo_is_sealed in tobjectdef(obj).objectoptions then
|
||||
AsmWrite('final ');
|
||||
if oo_is_abstract in tobjectdef(obj).objectoptions then
|
||||
if (oo_is_abstract in tobjectdef(obj).objectoptions) or
|
||||
(tobjectdef(obj).abstractcnt<>0) then
|
||||
AsmWrite('abstract ');
|
||||
if toplevelowner.symtabletype=globalsymtable then
|
||||
AsmWrite('public ');
|
||||
|
@ -2456,6 +2456,9 @@ implementation
|
||||
end;
|
||||
if not assigned(objectdf) then
|
||||
exit;
|
||||
{ quick exit if nothing to check }
|
||||
if objectdf.abstractcnt = 0 then
|
||||
exit;
|
||||
|
||||
parents := tlinkedlist.create;
|
||||
AbstractMethodsList := TFPHashList.create;
|
||||
|
@ -384,6 +384,12 @@ implementation
|
||||
vmtentryvis:=pd.visibility;
|
||||
end;
|
||||
|
||||
{ in case we are overriding an abstract method,
|
||||
decrease the number of abstract methods in this class }
|
||||
if (po_overridingmethod in pd.procoptions) and
|
||||
(po_abstractmethod in vmtpd.procoptions) then
|
||||
dec(tobjectdef(pd.owner.defowner).abstractcnt);
|
||||
|
||||
{ override old virtual method in VMT }
|
||||
if updatevalues then
|
||||
begin
|
||||
|
@ -1667,7 +1667,11 @@ begin
|
||||
(oo_is_sealed in tprocdef(pd).struct.objectoptions) then
|
||||
Message(parser_e_sealed_class_cannot_have_abstract_methods)
|
||||
else if (po_virtualmethod in pd.procoptions) then
|
||||
include(pd.procoptions,po_abstractmethod)
|
||||
begin
|
||||
include(pd.procoptions,po_abstractmethod);
|
||||
{ one more abstract method }
|
||||
inc(tobjectdef(pd.owner.defowner).abstractcnt);
|
||||
end
|
||||
else
|
||||
Message(parser_e_only_virtual_methods_abstract);
|
||||
{ the method is defined }
|
||||
|
@ -43,7 +43,7 @@ type
|
||||
{$endif Test_Double_checksum}
|
||||
|
||||
const
|
||||
CurrentPPUVersion = 136;
|
||||
CurrentPPUVersion = 137;
|
||||
|
||||
{ buffer sizes }
|
||||
maxentrysize = 1024;
|
||||
|
@ -284,6 +284,10 @@ interface
|
||||
iidstr : pshortstring;
|
||||
{ store implemented interfaces defs and name mappings }
|
||||
ImplementedInterfaces : TFPObjectList;
|
||||
{ number of abstract methods (used by JVM target to determine whether
|
||||
or not the class should be marked as abstract: must be done if 1 or
|
||||
more abstract methods) }
|
||||
abstractcnt : longint;
|
||||
writing_class_record_dbginfo,
|
||||
{ a class of this type has been created in this module }
|
||||
created_in_current_module,
|
||||
@ -4902,6 +4906,7 @@ implementation
|
||||
ppufile.getguid(iidguid^);
|
||||
iidstr:=stringdup(ppufile.getstring);
|
||||
end;
|
||||
abstractcnt:=ppufile.getlongint;
|
||||
|
||||
if objecttype=odt_helper then
|
||||
ppufile.getderef(extendeddefderef);
|
||||
@ -5038,6 +5043,7 @@ implementation
|
||||
end;
|
||||
if assigned(iidstr) then
|
||||
tobjectdef(result).iidstr:=stringdup(iidstr^);
|
||||
tobjectdef(result).abstractcnt:=abstractcnt;
|
||||
if assigned(ImplementedInterfaces) then
|
||||
begin
|
||||
for i:=0 to ImplementedInterfaces.count-1 do
|
||||
@ -5084,6 +5090,7 @@ implementation
|
||||
ppufile.putguid(iidguid^);
|
||||
ppufile.putstring(iidstr^);
|
||||
end;
|
||||
ppufile.putlongint(abstractcnt);
|
||||
if objecttype=odt_helper then
|
||||
ppufile.putderef(extendeddefderef);
|
||||
|
||||
@ -5313,6 +5320,8 @@ implementation
|
||||
exit;
|
||||
{ inherit options and status }
|
||||
objectoptions:=objectoptions+(c.objectoptions*inherited_objectoptions);
|
||||
{ initially has the same number of abstract methods as the parent }
|
||||
abstractcnt:=c.abstractcnt;
|
||||
{ add the data of the anchestor class/object }
|
||||
if (objecttype in [odt_class,odt_object,odt_objcclass,odt_javaclass]) then
|
||||
begin
|
||||
|
@ -2055,6 +2055,8 @@ begin
|
||||
writeln(space,' IID String : ',getstring);
|
||||
end;
|
||||
|
||||
writeln(space,' Abstract methods : ',getlongint);
|
||||
|
||||
if (tobjecttyp(b)=odt_helper) or
|
||||
(oo_is_classhelper in current_objectoptions) then
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user