* self fixes for static methods (merged)

This commit is contained in:
peter 2003-01-30 21:46:57 +00:00
parent a3c3fb9282
commit 25d973ef16
6 changed files with 151 additions and 77 deletions

View File

@ -712,7 +712,7 @@ implementation
{ extended syntax of new }
{ ESI must be zero }
r.enum:=self_pointer_reg;
rg.getexplicitregisterint(exprasmlist,R_ESI);
rg.getexplicitregisterint(exprasmlist,r.enum);
cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r);
cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(2));
{ insert the vmt }
@ -764,15 +764,22 @@ implementation
But, not for a class method via self }
if not(po_containsself in procdefinition.procoptions) then
begin
if (po_classmethod in procdefinition.procoptions) and
not(methodpointer.resulttype.def.deftype=classrefdef) then
if (po_staticmethod in procdefinition.procoptions) or
((po_classmethod in procdefinition.procoptions) and
not(methodpointer.resulttype.def.deftype=classrefdef)) then
begin
{ class method needs current VMT }
r.enum:=self_pointer_reg;
rg.getexplicitregisterint(exprasmlist,R_ESI);
reference_reset_base(href,r,tprocdef(procdefinition)._class.vmt_offset);
cg.g_maybe_testself(exprasmlist);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r);
r.enum:=self_pointer_reg;
rg.getexplicitregisterint(exprasmlist,r.enum);
if not(oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r)
else
begin
{ class method and static methods needs current VMT }
cg.g_maybe_testself(exprasmlist,r);
reference_reset_base(href,r,tprocdef(procdefinition)._class.vmt_offset);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r);
cg.g_maybe_testvmt(exprasmlist,r,tprocdef(procdefinition)._class);
end;
end;
{ direct call to destructor: remove data }
@ -823,18 +830,29 @@ implementation
end
else
begin
if (po_classmethod in procdefinition.procoptions) and
not(
assigned(aktprocdef) and
(po_classmethod in aktprocdef.procoptions)
) then
if (
(po_classmethod in procdefinition.procoptions) and
not(assigned(aktprocdef) and
(po_classmethod in aktprocdef.procoptions))
) or
(
(po_staticmethod in procdefinition.procoptions) and
not(assigned(aktprocdef) and
(po_staticmethod in aktprocdef.procoptions))
) then
begin
{ class method needs current VMT }
rg.getexplicitregisterint(exprasmlist,R_ESI);
r.enum:=R_ESI;
reference_reset_base(href,r,tprocdef(procdefinition)._class.vmt_offset);
cg.g_maybe_testself(exprasmlist);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r);
r.enum:=self_pointer_reg;
rg.getexplicitregisterint(exprasmlist,r.enum);
if not(oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r)
else
begin
{ class method and static methods needs current VMT }
cg.g_maybe_testself(exprasmlist,r);
reference_reset_base(href,r,tprocdef(procdefinition)._class.vmt_offset);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r);
cg.g_maybe_testvmt(exprasmlist,r,tprocdef(procdefinition)._class);
end;
end
else
begin
@ -983,9 +1001,9 @@ implementation
end
else
begin
cg.g_maybe_testself(exprasmlist,r);
{ this is one point where we need vmt_offset (PM) }
reference_reset_base(href,r,tprocdef(procdefinition)._class.vmt_offset);
cg.g_maybe_testself(exprasmlist);
tmpreg:=cg.get_scratch_reg_address(exprasmlist);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,tmpreg);
reference_reset_base(href,tmpreg,0);
@ -1002,20 +1020,7 @@ implementation
href.offset:=tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber);
if not(is_interface(tprocdef(procdefinition)._class)) and
not(is_cppclass(tprocdef(procdefinition)._class)) then
begin
if (cs_check_object in aktlocalswitches) then
begin
reference_reset_symbol(hrefvmt,objectlibrary.newasmsymbol(tprocdef(procdefinition)._class.vmt_mangledname),0);
cg.a_paramaddr_ref(exprasmlist,hrefvmt,paramanager.getintparaloc(2));
cg.a_param_reg(exprasmlist,OS_ADDR,href.base,paramanager.getintparaloc(1));
cg.a_call_name(exprasmlist,'FPC_CHECK_OBJECT_EXT');
end
else if (cs_check_range in aktlocalswitches) then
begin
cg.a_param_reg(exprasmlist,OS_ADDR,href.base,paramanager.getintparaloc(1));
cg.a_call_name(exprasmlist,'FPC_CHECK_OBJECT');
end;
end;
cg.g_maybe_testvmt(exprasmlist,href.base,tprocdef(procdefinition)._class);
cg.a_call_ref(exprasmlist,href);
if release_tmpreg then
cg.free_scratch_reg(exprasmlist,tmpreg);
@ -1277,7 +1282,10 @@ begin
end.
{
$Log$
Revision 1.80 2003-01-13 18:37:44 daniel
Revision 1.81 2003-01-30 21:46:57 peter
* self fixes for static methods (merged)
Revision 1.80 2003/01/13 18:37:44 daniel
* Work on register conversion
Revision 1.79 2003/01/08 18:43:57 daniel

View File

@ -922,14 +922,22 @@ implementation
But, not for a class method via self }
if not(po_containsself in procdefinition.procoptions) then
begin
if (po_classmethod in procdefinition.procoptions) and
not(methodpointer.resulttype.def.deftype=classrefdef) then
if (po_staticmethod in procdefinition.procoptions) or
((po_classmethod in procdefinition.procoptions) and
not(methodpointer.resulttype.def.deftype=classrefdef)) then
begin
{ class method needs current VMT }
rg.getexplicitregisterint(exprasmlist,R_ESI);
reference_reset_base(href,R_ESI,tprocdef(procdefinition)._class.vmt_offset);
cg.a_maybe_testself(exprasmlist);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,self_pointer_reg);
r.enum:=self_pointer_reg;
rg.getexplicitregisterint(exprasmlist,r.enum);
if not(oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r)
else
begin
{ class method and static methods needs current VMT }
cg.g_maybe_testself(exprasmlist,r);
reference_reset_base(href,r,tprocdef(procdefinition)._class.vmt_offset);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r);
cg.g_maybe_testvmt(exprasmlist,r,tprocdef(procdefinition)._class);
end;
end;
{ direct call to destructor: remove data }
@ -979,17 +987,29 @@ implementation
end
else
begin
if (po_classmethod in procdefinition.procoptions) and
not(
assigned(aktprocdef) and
(po_classmethod in aktprocdef.procoptions)
) then
if (
(po_classmethod in procdefinition.procoptions) and
not(assigned(aktprocdef) and
(po_classmethod in aktprocdef.procoptions))
) or
(
(po_staticmethod in procdefinition.procoptions) and
not(assigned(aktprocdef) and
(po_staticmethod in aktprocdef.procoptions))
) then
begin
{ class method needs current VMT }
rg.getexplicitregisterint(exprasmlist,R_ESI);
reference_reset_base(href,R_ESI,tprocdef(procdefinition)._class.vmt_offset);
cg.a_maybe_testself(exprasmlist);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,R_ESI);
r.enum:=self_pointer_reg;
rg.getexplicitregisterint(exprasmlist,r.enum);
if not(oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
cg.a_load_const_reg(exprasmlist,OS_ADDR,0,r)
else
begin
{ class method and static methods needs current VMT }
cg.g_maybe_testself(exprasmlist,r);
reference_reset_base(href,r,tprocdef(procdefinition)._class.vmt_offset);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r);
cg.g_maybe_testvmt(exprasmlist,r,tprocdef(procdefinition)._class);
end;
end
else
begin
@ -1113,20 +1133,7 @@ implementation
href.offset:=tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber);
if not(is_interface(tprocdef(procdefinition)._class)) and
not(is_cppclass(tprocdef(procdefinition)._class)) then
begin
if (cs_check_object in aktlocalswitches) then
begin
reference_reset_symbol(hrefvmt,objectlibrary.newasmsymbol(tprocdef(procdefinition)._class.vmt_mangledname),0);
cg.a_paramaddr_ref(exprasmlist,hrefvmt,2);
cg.a_param_reg(exprasmlist,OS_ADDR,href.base,1);
cg.a_call_name(exprasmlist,'FPC_CHECK_OBJECT_EXT');
end
else if (cs_check_range in aktlocalswitches) then
begin
cg.a_param_reg(exprasmlist,OS_ADDR,href.base,1);
cg.a_call_name(exprasmlist,'FPC_CHECK_OBJECT');
end;
end;
cg.g_maybe_testvmt(exprasmlist,href.base,tprocdef(procdefinition)._class);
cg.a_call_ref(exprasmlist,href);
if release_tmpreg then
cg.free_scratch_reg(exprasmlist,tmpreg);
@ -1572,7 +1579,10 @@ begin
end.
{
$Log$
Revision 1.35 2003-01-22 20:45:15 mazen
Revision 1.36 2003-01-30 21:46:57 peter
* self fixes for static methods (merged)
Revision 1.35 2003/01/22 20:45:15 mazen
* making math code in RTL compiling.
*NB : This does NOT mean necessary that it will generate correct code!

View File

@ -54,7 +54,7 @@ implementation
uses
globtype,systems,
cutils,verbose,globals,fmodule,
symconst,symdef,defutil,
symconst,symdef,defutil,symsym,
aasmbase,aasmtai,aasmcpu,
cginfo,cgbase,pass_1,pass_2,
cpubase,paramgr,
@ -220,7 +220,8 @@ implementation
{ second_handle_ the sizeof and typeof routines }
procedure tcginlinenode.second_SizeOfTypeOf;
var
href : treference;
href,
hrefvmt : treference;
hregister : tregister;
begin
location_reset(location,LOC_REGISTER,OS_ADDR);
@ -236,6 +237,45 @@ implementation
secondpass(left);
location_release(exprasmlist,left.location);
hregister:=rg.getaddressregister(exprasmlist);
{ handle self inside a method of a class }
case left.location.loc of
LOC_CREGISTER,
LOC_REGISTER :
begin
if (left.resulttype.def.deftype=classrefdef) or
(po_staticmethod in aktprocdef.procoptions) then
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,left.location.register,hregister)
else
begin
{ load VMT pointer }
reference_reset_base(hrefvmt,left.location.register,tobjectdef(left.resulttype.def).vmt_offset);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,hrefvmt,hregister);
end
end;
LOC_REFERENCE,
LOC_CREFERENCE :
begin
if is_class(left.resulttype.def) then
begin
{ deref class }
cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister);
{ load VMT pointer }
reference_reset_base(hrefvmt,hregister,tobjectdef(left.resulttype.def).vmt_offset);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,hrefvmt,hregister);
end
else
begin
{ load VMT pointer, but not for classrefdefs }
if (left.resulttype.def.deftype=objectdef) then
inc(left.location.reference.offset,tobjectdef(left.resulttype.def).vmt_offset);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister);
end;
end;
else
internalerror(200301301);
end;
{ load VMT pointer }
inc(left.location.reference.offset,tobjectdef(left.resulttype.def).vmt_offset);
cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister);
@ -612,7 +652,10 @@ end.
{
$Log$
Revision 1.18 2003-01-08 18:43:56 daniel
Revision 1.19 2003-01-30 21:46:57 peter
* self fixes for static methods (merged)
Revision 1.18 2003/01/08 18:43:56 daniel
* Tregister changed into a record
Revision 1.17 2002/11/25 17:43:18 peter

View File

@ -349,7 +349,8 @@ implementation
begin
rg.getexplicitregisterint(exprasmlist,SELF_POINTER_REG);
if (resulttype.def.deftype=classrefdef) or
is_class(resulttype.def) then
(is_class(resulttype.def) or
(po_staticmethod in aktprocdef.procoptions)) then
begin
location_reset(location,LOC_CREGISTER,OS_ADDR);
location.register.enum:=SELF_POINTER_REG;
@ -924,7 +925,10 @@ begin
end.
{
$Log$
Revision 1.40 2003-01-08 18:43:56 daniel
Revision 1.41 2003-01-30 21:46:57 peter
* self fixes for static methods (merged)
Revision 1.40 2003/01/08 18:43:56 daniel
* Tregister changed into a record
Revision 1.39 2002/12/20 18:13:19 peter

View File

@ -911,7 +911,8 @@ implementation
begin
result:=nil;
if (resulttype.def.deftype=classrefdef) or
is_class(resulttype.def) then
is_class(resulttype.def) or
(po_staticmethod in aktprocdef.procoptions) then
location.loc:=LOC_CREGISTER
else
location.loc:=LOC_REFERENCE;
@ -1054,7 +1055,10 @@ begin
end.
{
$Log$
Revision 1.45 2003-01-09 21:52:37 peter
Revision 1.46 2003-01-30 21:46:57 peter
* self fixes for static methods (merged)
Revision 1.45 2003/01/09 21:52:37 peter
* merged some verbosity options.
* V_LineInfo is a verbosity flag to include line info

View File

@ -315,7 +315,9 @@ implementation
consume(_RKLAMMER);
if p1.nodetype=typen then
ttypenode(p1).allowed:=true;
if p1.resulttype.def.deftype=objectdef then
if (p1.resulttype.def.deftype = objectdef) or
((p1.resulttype.def.deftype = classrefdef) and
(p1.nodetype in [selfn,loadvmtn])) then
statement_syssym:=geninlinenode(in_typeof_x,false,p1)
else
begin
@ -2324,7 +2326,10 @@ implementation
end.
{
$Log$
Revision 1.101 2003-01-16 22:12:22 peter
Revision 1.102 2003-01-30 21:46:57 peter
* self fixes for static methods (merged)
Revision 1.101 2003/01/16 22:12:22 peter
* Find the correct procvar to load when using @ in fpc mode
Revision 1.100 2003/01/15 01:44:32 peter