* 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:
peter 2005-01-04 16:36:31 +00:00
parent b537382710
commit 720815e13b
2 changed files with 122 additions and 53 deletions

View File

@ -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

View File

@ -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