* 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,6 +1216,31 @@ 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);
{ Handle classes and legacy objects separate to make it
more maintainable }
if (methodpointer.resulttype.def.deftype=classrefdef) then
begin
if not is_class(tclassrefdef(methodpointer.resulttype.def).pointertype.def) then
internalerror(200501041);
{ constructor call via classreference => allocate memory }
if (procdefinition.proctypeoption=potype_constructor) then
begin
vmttree:=methodpointer.getcopy;
{ Only a typenode can be passed when it is called with <class of xx>.create }
if vmttree.nodetype=typen then
vmttree:=cloadvmtaddrnode.create(vmttree);
end
else
begin
{ Call afterconstruction }
vmttree:=cpointerconstnode.create(1,voidpointertype);
end;
end
else
{ Class style objects }
if is_class(methodpointer.resulttype.def) then
begin
{ inherited call, no create/destroy } { inherited call, no create/destroy }
if (cnf_inherited in callnodeflags) then if (cnf_inherited in callnodeflags) then
vmttree:=cpointerconstnode.create(0,voidpointertype) vmttree:=cpointerconstnode.create(0,voidpointertype)
@ -1224,13 +1249,48 @@ type
without specifying self explicit } without specifying self explicit }
if (cnf_member_call in callnodeflags) then if (cnf_member_call in callnodeflags) then
begin begin
if (methodpointer.resulttype.def.deftype=classrefdef) and { destructor: don't release instance, vmt=0
(procdefinition.proctypeoption=potype_constructor) then constructor:
vmttree:=methodpointer.getcopy if called from a constructor in the same class then
don't call afterconstruction, vmt=0
else else
vmttree:=cpointerconstnode.create(0,voidpointertype); 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 end
else 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
else
{ Old style object }
begin
{ constructor with extended syntax called from new } { constructor with extended syntax called from new }
if (cnf_new_call in callnodeflags) then if (cnf_new_call in callnodeflags) then
vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype)) vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype))
@ -1239,45 +1299,35 @@ type
if (cnf_dispose_call in callnodeflags) then if (cnf_dispose_call in callnodeflags) then
vmttree:=cloadvmtaddrnode.create(methodpointer.getcopy) vmttree:=cloadvmtaddrnode.create(methodpointer.getcopy)
else else
if (methodpointer.resulttype.def.deftype=classrefdef) then { inherited call, no create/destroy }
if (cnf_inherited in callnodeflags) then
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 begin
{ constructor call via classreference => allocate memory } { destructor: don't release instance, vmt=0
if (procdefinition.proctypeoption=potype_constructor) and constructor: don't initialize instance, vmt=0 }
is_class(tclassrefdef(methodpointer.resulttype.def).pointertype.def) then vmttree:=cpointerconstnode.create(0,voidpointertype)
begin
vmttree:=methodpointer.getcopy;
{ Only a typenode can be passed when it is called with <class of xx>.create }
if vmttree.nodetype=typen then
vmttree:=cloadvmtaddrnode.create(vmttree);
end end
else else
vmttree:=cpointerconstnode.create(0,voidpointertype); { normal object call like obj.proc }
end
else
{ class }
if is_class(methodpointer.resulttype.def) then
begin
{ destructor: release instance, flag(vmt)=1
constructor: direct call, do nothing, leave vmt=0 }
if (procdefinition.proctypeoption=potype_destructor) then
vmttree:=cpointerconstnode.create(1,voidpointertype)
else
vmttree:=cpointerconstnode.create(0,voidpointertype);
end
else
{ object }
begin begin
{ destructor: direct call, no dispose, vmt=0 { destructor: direct call, no dispose, vmt=0
constructor: initialize object, load vmt } constructor: initialize object, load vmt }
if (procdefinition.proctypeoption=potype_constructor) then if (procdefinition.proctypeoption=potype_constructor) then
begin
{ old styled inherited call? } { old styled inherited call? }
if (methodpointer.nodetype=typen) then if (methodpointer.nodetype=typen) then
vmttree:=cpointerconstnode.create(0,voidpointertype) vmttree:=cpointerconstnode.create(0,voidpointertype)
else else
vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype)) vmttree:=cloadvmtaddrnode.create(ctypenode.create(methodpointer.resulttype))
end
else else
vmttree:=cpointerconstnode.create(0,voidpointertype); vmttree:=cpointerconstnode.create(0,voidpointertype);
end; 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,
ctypeconvnode.create_internal(
load_vmt_pointer_node, load_vmt_pointer_node,
cnilnode.create), 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