From 9cbff6f5a67f683eb3bfc12d71101800c2934681 Mon Sep 17 00:00:00 2001 From: Jonas Maebe <jonas@freepascal.org> Date: Thu, 24 Jan 2013 09:45:12 +0000 Subject: [PATCH] + support for record constructors for the JVM target git-svn-id: trunk@23510 - --- compiler/jvm/njvmcal.pas | 6 ++++++ compiler/ncal.pas | 25 ++++++++++++++++++------- compiler/psub.pas | 9 +++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/compiler/jvm/njvmcal.pas b/compiler/jvm/njvmcal.pas index ec3c6c80b5..d1ebac0620 100644 --- a/compiler/jvm/njvmcal.pas +++ b/compiler/jvm/njvmcal.pas @@ -387,6 +387,12 @@ implementation exit; if not(methodpointer.resultdef.typ in [classrefdef,recorddef]) then 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)))); { the constructor doesn't return anything, so put a duplicate of the self pointer on the evaluation stack for use as function result diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 22501bd764..bc2a9a813d 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -692,7 +692,9 @@ implementation if assigned(parasym) and (target_info.system in systems_managed_vm) 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); if assigned(fparainit) then @@ -1780,12 +1782,21 @@ implementation if methodpointer.nodetype=typen then if (methodpointer.resultdef.typ=recorddef) then begin - { TSomeRecord.Constructor call. We need to allocate } - { self node as a temp node of the result type } - temp:=ctempcreatenode.create(methodpointer.resultdef,methodpointer.resultdef.size,tt_persistent,false); - add_init_statement(temp); - add_done_statement(ctempdeletenode.create_normal_temp(temp)); - selftree:=ctemprefnode.create(temp); + if not(target_info.system in systems_jvm) then + begin + { TSomeRecord.Constructor call. We need to allocate } + { self node as a temp node of the result type } + temp:=ctempcreatenode.create(methodpointer.resultdef,methodpointer.resultdef.size,tt_persistent,false); + 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 else selftree:=load_self_node diff --git a/compiler/psub.pas b/compiler/psub.pas index c1e1fcefd6..21a5d8c798 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -474,13 +474,18 @@ implementation ccallnode.createintern('fpc_help_constructor',para))); end 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 if (current_procinfo.procdef.proctypeoption=potype_constructor) and not current_procinfo.ConstructorCallingConstructor then begin { 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 (srsym.typ=procsym) then begin