mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-08 08:06:11 +02:00
* fix aftercosntruction calls, vmt=1 is used to indicate that
afterconstruction needs to be called * only accept resourcestring when objpas is loaded
This commit is contained in:
parent
b537382710
commit
720815e13b
@ -1216,34 +1216,15 @@ type
|
|||||||
if not(procdefinition.proctypeoption in [potype_constructor,potype_destructor]) then
|
if not(procdefinition.proctypeoption in [potype_constructor,potype_destructor]) then
|
||||||
internalerror(200305051);
|
internalerror(200305051);
|
||||||
|
|
||||||
{ inherited call, no create/destroy }
|
{ Handle classes and legacy objects separate to make it
|
||||||
if (cnf_inherited in callnodeflags) then
|
more maintainable }
|
||||||
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
if (methodpointer.resulttype.def.deftype=classrefdef) then
|
||||||
else
|
|
||||||
{ do not create/destroy when called from member function
|
|
||||||
without specifying self explicit }
|
|
||||||
if (cnf_member_call in callnodeflags) then
|
|
||||||
begin
|
|
||||||
if (methodpointer.resulttype.def.deftype=classrefdef) and
|
|
||||||
(procdefinition.proctypeoption=potype_constructor) then
|
|
||||||
vmttree:=methodpointer.getcopy
|
|
||||||
else
|
|
||||||
vmttree:=cpointerconstnode.create(0,voidpointertype);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
{ constructor with extended syntax called from new }
|
|
||||||
if (cnf_new_call in callnodeflags) then
|
|
||||||
vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype))
|
|
||||||
else
|
|
||||||
{ destructor with extended syntax called from dispose }
|
|
||||||
if (cnf_dispose_call in callnodeflags) then
|
|
||||||
vmttree:=cloadvmtaddrnode.create(methodpointer.getcopy)
|
|
||||||
else
|
|
||||||
if (methodpointer.resulttype.def.deftype=classrefdef) then
|
|
||||||
begin
|
begin
|
||||||
|
if not is_class(tclassrefdef(methodpointer.resulttype.def).pointertype.def) then
|
||||||
|
internalerror(200501041);
|
||||||
|
|
||||||
{ constructor call via classreference => allocate memory }
|
{ constructor call via classreference => allocate memory }
|
||||||
if (procdefinition.proctypeoption=potype_constructor) and
|
if (procdefinition.proctypeoption=potype_constructor) then
|
||||||
is_class(tclassrefdef(methodpointer.resulttype.def).pointertype.def) then
|
|
||||||
begin
|
begin
|
||||||
vmttree:=methodpointer.getcopy;
|
vmttree:=methodpointer.getcopy;
|
||||||
{ Only a typenode can be passed when it is called with <class of xx>.create }
|
{ Only a typenode can be passed when it is called with <class of xx>.create }
|
||||||
@ -1251,33 +1232,102 @@ type
|
|||||||
vmttree:=cloadvmtaddrnode.create(vmttree);
|
vmttree:=cloadvmtaddrnode.create(vmttree);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
vmttree:=cpointerconstnode.create(0,voidpointertype);
|
begin
|
||||||
|
{ Call afterconstruction }
|
||||||
|
vmttree:=cpointerconstnode.create(1,voidpointertype);
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{ class }
|
{ Class style objects }
|
||||||
if is_class(methodpointer.resulttype.def) then
|
if is_class(methodpointer.resulttype.def) then
|
||||||
begin
|
begin
|
||||||
{ destructor: release instance, flag(vmt)=1
|
{ inherited call, no create/destroy }
|
||||||
constructor: direct call, do nothing, leave vmt=0 }
|
if (cnf_inherited in callnodeflags) then
|
||||||
if (procdefinition.proctypeoption=potype_destructor) then
|
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||||
vmttree:=cpointerconstnode.create(1,voidpointertype)
|
|
||||||
else
|
else
|
||||||
vmttree:=cpointerconstnode.create(0,voidpointertype);
|
{ do not create/destroy when called from member function
|
||||||
|
without specifying self explicit }
|
||||||
|
if (cnf_member_call in callnodeflags) then
|
||||||
|
begin
|
||||||
|
{ destructor: don't release instance, vmt=0
|
||||||
|
constructor:
|
||||||
|
if called from a constructor in the same class then
|
||||||
|
don't call afterconstruction, vmt=0
|
||||||
|
else
|
||||||
|
call afterconstrution, vmt=1 }
|
||||||
|
if (procdefinition.proctypeoption=potype_destructor) then
|
||||||
|
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (current_procinfo.procdef.proctypeoption=potype_constructor) and
|
||||||
|
(procdefinition.proctypeoption=potype_constructor) then
|
||||||
|
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||||
|
else
|
||||||
|
vmttree:=cpointerconstnode.create(1,voidpointertype);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{ normal call to method like cl1.proc }
|
||||||
|
begin
|
||||||
|
{ destructor: release instance, vmt=1
|
||||||
|
constructor:
|
||||||
|
if called from a constructor in the same class using self.create then
|
||||||
|
don't call afterconstruction, vmt=0
|
||||||
|
else
|
||||||
|
call afterconstrution, vmt=1 }
|
||||||
|
if (procdefinition.proctypeoption=potype_destructor) then
|
||||||
|
vmttree:=cpointerconstnode.create(1,voidpointertype)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (current_procinfo.procdef.proctypeoption=potype_constructor) and
|
||||||
|
(procdefinition.proctypeoption=potype_constructor) and
|
||||||
|
(nf_is_self in methodpointer.flags) then
|
||||||
|
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||||
|
else
|
||||||
|
vmttree:=cpointerconstnode.create(1,voidpointertype);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{ object }
|
{ Old style object }
|
||||||
begin
|
begin
|
||||||
{ destructor: direct call, no dispose, vmt=0
|
{ constructor with extended syntax called from new }
|
||||||
constructor: initialize object, load vmt }
|
if (cnf_new_call in callnodeflags) then
|
||||||
if (procdefinition.proctypeoption=potype_constructor) then
|
vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype))
|
||||||
{ old styled inherited call? }
|
else
|
||||||
if (methodpointer.nodetype=typen) then
|
{ destructor with extended syntax called from dispose }
|
||||||
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
if (cnf_dispose_call in callnodeflags) then
|
||||||
else
|
vmttree:=cloadvmtaddrnode.create(methodpointer.getcopy)
|
||||||
vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype))
|
else
|
||||||
else
|
{ inherited call, no create/destroy }
|
||||||
vmttree:=cpointerconstnode.create(0,voidpointertype);
|
if (cnf_inherited in callnodeflags) then
|
||||||
end;
|
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||||
|
else
|
||||||
|
{ do not create/destroy when called from member function
|
||||||
|
without specifying self explicit }
|
||||||
|
if (cnf_member_call in callnodeflags) then
|
||||||
|
begin
|
||||||
|
{ destructor: don't release instance, vmt=0
|
||||||
|
constructor: don't initialize instance, vmt=0 }
|
||||||
|
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{ normal object call like obj.proc }
|
||||||
|
begin
|
||||||
|
{ destructor: direct call, no dispose, vmt=0
|
||||||
|
constructor: initialize object, load vmt }
|
||||||
|
if (procdefinition.proctypeoption=potype_constructor) then
|
||||||
|
begin
|
||||||
|
{ old styled inherited call? }
|
||||||
|
if (methodpointer.nodetype=typen) then
|
||||||
|
vmttree:=cpointerconstnode.create(0,voidpointertype)
|
||||||
|
else
|
||||||
|
vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vmttree:=cpointerconstnode.create(0,voidpointertype);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
result:=vmttree;
|
result:=vmttree;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2445,7 +2495,12 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.274 2005-01-02 16:58:48 peter
|
Revision 1.275 2005-01-04 16:36:31 peter
|
||||||
|
* fix aftercosntruction calls, vmt=1 is used to indicate that
|
||||||
|
afterconstruction needs to be called
|
||||||
|
* only accept resourcestring when objpas is loaded
|
||||||
|
|
||||||
|
Revision 1.274 2005/01/02 16:58:48 peter
|
||||||
* Don't release methodpointer. It is maybe still needed when we need to
|
* Don't release methodpointer. It is maybe still needed when we need to
|
||||||
convert the calln to loadn
|
convert the calln to loadn
|
||||||
|
|
||||||
|
@ -272,11 +272,13 @@ implementation
|
|||||||
if assigned(srsym) and
|
if assigned(srsym) and
|
||||||
(srsym.typ=procsym) then
|
(srsym.typ=procsym) then
|
||||||
begin
|
begin
|
||||||
{ if vmt<>0 then newinstance }
|
{ if vmt>1 then newinstance }
|
||||||
addstatement(newstatement,cifnode.create(
|
addstatement(newstatement,cifnode.create(
|
||||||
caddnode.create(unequaln,
|
caddnode.create(gtn,
|
||||||
load_vmt_pointer_node,
|
ctypeconvnode.create_internal(
|
||||||
cnilnode.create),
|
load_vmt_pointer_node,
|
||||||
|
voidpointertype),
|
||||||
|
cpointerconstnode.create(1,voidpointertype)),
|
||||||
cassignmentnode.create(
|
cassignmentnode.create(
|
||||||
ctypeconvnode.create_internal(
|
ctypeconvnode.create_internal(
|
||||||
load_self_pointer_node,
|
load_self_pointer_node,
|
||||||
@ -1393,7 +1395,14 @@ implementation
|
|||||||
begin
|
begin
|
||||||
case idtoken of
|
case idtoken of
|
||||||
_RESOURCESTRING :
|
_RESOURCESTRING :
|
||||||
resourcestring_dec;
|
begin
|
||||||
|
{ m_class is needed, because the resourcestring
|
||||||
|
loading is in the ObjPas unit }
|
||||||
|
if (m_class in aktmodeswitches) then
|
||||||
|
resourcestring_dec
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end;
|
||||||
_PROPERTY:
|
_PROPERTY:
|
||||||
begin
|
begin
|
||||||
if (m_fpc in aktmodeswitches) then
|
if (m_fpc in aktmodeswitches) then
|
||||||
@ -1459,7 +1468,12 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.228 2005-01-03 22:27:56 peter
|
Revision 1.229 2005-01-04 16:36:31 peter
|
||||||
|
* fix aftercosntruction calls, vmt=1 is used to indicate that
|
||||||
|
afterconstruction needs to be called
|
||||||
|
* only accept resourcestring when objpas is loaded
|
||||||
|
|
||||||
|
Revision 1.228 2005/01/03 22:27:56 peter
|
||||||
* insert stack_check helper call before doing register allocation
|
* insert stack_check helper call before doing register allocation
|
||||||
so the used registers can't be reused when parameters are loaded
|
so the used registers can't be reused when parameters are loaded
|
||||||
into register variables
|
into register variables
|
||||||
|
Loading…
Reference in New Issue
Block a user