+ support for record constructors for the JVM target

git-svn-id: trunk@23510 -
This commit is contained in:
Jonas Maebe 2013-01-24 09:45:12 +00:00
parent 3abc7b0d9c
commit 9cbff6f5a6
3 changed files with 31 additions and 9 deletions

View File

@ -387,6 +387,12 @@ implementation
exit; exit;
if not(methodpointer.resultdef.typ in [classrefdef,recorddef]) then if not(methodpointer.resultdef.typ in [classrefdef,recorddef]) then
exit; exit;
{ in case of an inherited constructor call in a class, the methodpointer
is an objectdef rather than a classrefdef. That's not true in case
of records though, so we need an extra check }
if (current_procinfo.procdef.proctypeoption=potype_constructor) and
(cnf_inherited in callnodeflags) then
exit;
current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_new,current_asmdata.RefAsmSymbol(tabstractrecorddef(procdefinition.owner.defowner).jvm_full_typename(true)))); current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_new,current_asmdata.RefAsmSymbol(tabstractrecorddef(procdefinition.owner.defowner).jvm_full_typename(true))));
{ the constructor doesn't return anything, so put a duplicate of the { the constructor doesn't return anything, so put a duplicate of the
self pointer on the evaluation stack for use as function result self pointer on the evaluation stack for use as function result

View File

@ -692,7 +692,9 @@ implementation
if assigned(parasym) and if assigned(parasym) and
(target_info.system in systems_managed_vm) and (target_info.system in systems_managed_vm) and
(parasym.varspez in [vs_var,vs_out,vs_constref]) and (parasym.varspez in [vs_var,vs_out,vs_constref]) and
(parasym.vardef.typ<>formaldef) then (parasym.vardef.typ<>formaldef) and
{ for record constructors }
(left.nodetype<>nothingn) then
handlemanagedbyrefpara(left.resultdef); handlemanagedbyrefpara(left.resultdef);
if assigned(fparainit) then if assigned(fparainit) then
@ -1780,12 +1782,21 @@ implementation
if methodpointer.nodetype=typen then if methodpointer.nodetype=typen then
if (methodpointer.resultdef.typ=recorddef) then if (methodpointer.resultdef.typ=recorddef) then
begin begin
{ TSomeRecord.Constructor call. We need to allocate } if not(target_info.system in systems_jvm) then
{ self node as a temp node of the result type } begin
temp:=ctempcreatenode.create(methodpointer.resultdef,methodpointer.resultdef.size,tt_persistent,false); { TSomeRecord.Constructor call. We need to allocate }
add_init_statement(temp); { self node as a temp node of the result type }
add_done_statement(ctempdeletenode.create_normal_temp(temp)); temp:=ctempcreatenode.create(methodpointer.resultdef,methodpointer.resultdef.size,tt_persistent,false);
selftree:=ctemprefnode.create(temp); add_init_statement(temp);
add_done_statement(ctempdeletenode.create_normal_temp(temp));
selftree:=ctemprefnode.create(temp);
end
else
begin
{ special handling for Java constructors, handled in
tjvmcallnode.extra_pre_call_code }
selftree:=cnothingnode.create
end;
end end
else else
selftree:=load_self_node selftree:=load_self_node

View File

@ -474,13 +474,18 @@ implementation
ccallnode.createintern('fpc_help_constructor',para))); ccallnode.createintern('fpc_help_constructor',para)));
end end
else else
if is_javaclass(current_structdef) then if is_javaclass(current_structdef) or
((target_info.system in systems_jvm) and
is_record(current_structdef)) then
begin begin
if (current_procinfo.procdef.proctypeoption=potype_constructor) and if (current_procinfo.procdef.proctypeoption=potype_constructor) and
not current_procinfo.ConstructorCallingConstructor then not current_procinfo.ConstructorCallingConstructor then
begin begin
{ call inherited constructor } { call inherited constructor }
srsym:=search_struct_member(tobjectdef(current_structdef).childof,'CREATE'); if is_javaclass(current_structdef) then
srsym:=search_struct_member_no_helper(tobjectdef(current_structdef).childof,'CREATE')
else
srsym:=search_struct_member_no_helper(java_fpcbaserecordtype,'CREATE');
if assigned(srsym) and if assigned(srsym) and
(srsym.typ=procsym) then (srsym.typ=procsym) then
begin begin