mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 08:09:29 +02:00
* self fixes for static methods (merged)
This commit is contained in:
parent
a3c3fb9282
commit
25d973ef16
@ -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
|
||||
|
@ -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!
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user