* give an error when calling a virtual constructor from another constructor

on the JVM target, because the generated code was invalid and I can't think
    of a generic way to solve it (see added comments in njvmcal.pas)

git-svn-id: branches/jvmbackend@19055 -
This commit is contained in:
Jonas Maebe 2011-09-12 18:08:46 +00:00
parent 125c0cf225
commit 633de3fe30
4 changed files with 430 additions and 392 deletions

View File

@ -51,6 +51,7 @@ interface
function dispatch_procvar: tnode;
procedure remove_hidden_paras;
public
function pass_typecheck: tnode; override;
function pass_1: tnode; override;
end;
@ -58,7 +59,7 @@ interface
implementation
uses
verbose,globtype,constexp,cutils,
verbose,globals,globtype,constexp,cutils,
symconst,symtable,symsym,defutil,
cgutils,tgobj,procinfo,htypechk,
cpubase,aasmdata,aasmcpu,
@ -454,6 +455,37 @@ implementation
end;
function tjvmcallnode.pass_typecheck: tnode;
begin
result:=inherited pass_typecheck;
if assigned(result) or
codegenerror then
exit;
{ unfortunately, we cannot handle a call to a virtual constructor for
the current instance from inside another constructor. The reason is
that these must be called via reflection, but before an instance has
been fully initialized (which can only be done by calling either an
inherited constructor or another constructor of this class) you can't
perform reflection.
Replacing virtual constructors with plain virtual methods that are
called after the instance has been initialized causes problems if they
in turn call plain constructors from inside the JDK (you cannot call
constructors anymore once the instance has been constructed). It also
causes problems regarding which other constructor to call then instead
before to initialize the instance (we could add dummy constructors for
that purpose to Pascal classes, but that scheme breaks when a class
inherits from a JDK class other than JLObject).
}
if (current_procinfo.procdef.proctypeoption=potype_constructor) and
not(cnf_inherited in callnodeflags) and
(procdefinition.proctypeoption=potype_constructor) and
(po_virtualmethod in procdefinition.procoptions) and
(cnf_member_call in callnodeflags) then
CGMessage(parser_e_jvm_invalid_virtual_constructor_call);
end;
function tjvmcallnode.dispatch_procvar: tnode;
var
pdclass: tobjectdef;

View File

@ -379,7 +379,7 @@ scanner_w_directive_ignored_on_target=02089_W_Directive "$1" is ignored for the
#
# Parser
#
# 03319 is the last used one
# 03320 is the last used one
#
% \section{Parser messages}
% This section lists all parser messages. The parser takes care of the
@ -1426,6 +1426,11 @@ parser_d_internal_parser_string=03318_D_Parsing internally generated code: $1
% with debugging errors in them.
parser_e_feature_unsupported_for_vm=03319_E_This language feature is not supported on managed VM targets
% Certain language features are not supported on targets that are managed virtual machines.
parser_e_jvm_invalid_virtual_constructor_call=03320_E_Calling a virtual constructor for the current instance inside another constructor is not possible on the JVM target
% The JVM does not natively support virtual constructor. Unforunately, we are not aware of a way to
% emulate them in a way that makes it possible to support calling virtual constructors
% for the current instance inside another constructor.
%
% \end{description}
# Type Checking
#

View File

@ -412,6 +412,7 @@ const
parser_e_java_no_inherited_constructor=03317;
parser_d_internal_parser_string=03318;
parser_e_feature_unsupported_for_vm=03319;
parser_e_jvm_invalid_virtual_constructor_call=03320;
type_e_mismatch=04000;
type_e_incompatible_types=04001;
type_e_not_equal_types=04002;
@ -913,9 +914,9 @@ const
option_info=11024;
option_help_pages=11025;
MsgTxtSize = 62122;
MsgTxtSize = 62246;
MsgIdxMax : array[1..20] of longint=(
26,90,320,107,87,54,111,23,202,63,
26,90,321,107,87,54,111,23,202,63,
49,20,1,1,1,1,1,1,1,1
);

File diff suppressed because it is too large Load Diff