The cause of the internal error was the following:
We have a generic in an unit ("A") which uses another unit ("B") in the implementation section and this other unit uses unit A in the interface section. Now the generic is specialized in the interface section of B. This leads to the problem that in unit A when it tries to load the globalsymtable of unit B that globalsymtable will be Nil, because parsing of the interface section is not yet finished. Thus the change in pgenutil.pas, specialization_init: if the unit is still "in_interface" the localsymtable needs to be used instead of the globalsymtable.
This doesn't necessarily lead to a compiling test though, as there is the following possibility:
Unit A contains a generic class/record (with methods) and uses unit B in the implementation section. This unit B also contains a generic class/record (with methods) and uses unit A in the implementation section. Both units contain a specialization of the other unit's generic outside of it's own generics (such that generate_specialization is fully triggered). Let's assume compilation starts with unit A and we reach the uses of unit B. Now compilation switches to unit B and completes as unit A is already registered and in compilation. The problem now is that the generic in unit A still contains unresolved forward declarations as the implementation section of A was not yet parsed which will lead to "forward declaration not solved" errors (Note: Delphi compiles this).
The solution to this is the following: if a generic is specialized from another unit which is not in state ms_compiled then the unit of the specialization needs to wait for the unit of the generic. So the specialization's unit adds itself into a list of waiting units of the generic's unit. Now inside "proc_unit" we need to check whether this module is waiting for other modules and if so avoid "finishing" the unit (which means generating the methods of the specialization, generating assembler code and ultimately freeing the scanner and PPU). Now when the generic's unit finishes we need to check whether other modules are waiting for it and finish them (of course it's a bit more complicated in reality, but that pretty much sums it up).
+ globstat.pas: Added an unit which handles the saving and restoring of the global state which was originally inside "parser.pas, compile" so that Don't Repeat Yourself (DRY) is respected.
* fmodule.pas, tmodule:
+ add fields to keep track of the units the module is waiting for and which modules are waiting for the module
+ add field for the saved global state (raw pointer to avoid circles)
+ add field for the state which is needed to finish the unit (raw pointer to avoid circles)
+ move the code which was used in "parser.pas, compile" after a module was successfully compiled to the new virtual method "end_of_parsing"
+ fppu.pas, tppumodule.end_of_parsing:
free the ppufile here
* pgenutil.pas:
+ add new procedure "maybe_add_waiting_unit" which adds the specialization's unit to the waiting list of the generic if that unit is not yet compiled
* generate_specialization: call the new function when we add a new (true) specialization
* specialization_init: instead of not adding implementation units at all check whether the unit is still parsing the interface section and add the localsymtable in that case
* pmodules.pas:
* change "proc_unit" to a function which returns "true" if the unit was already finished (no need to wait for other units)
+ move the code from "proc_unit" from "generate_specialization_procs" on to a new procedure "finish_unit" which
* this procedure is either called immediately in "proc_unit" if the unit does not need to wait for other units or from "finish_unit" itself if a unit that is waiting for the given unit does no longer wait for another module (special care is taken in proc_unit to avoid circles)
* parser.pas, compile:
* correctly handle the case if an unit is not finished
* use the new global state functionality from globstat.pas
* pay special attention when calling "set_current_module" (see comment at that call)
+ add tests from 22160
+ add test for above mentioned "diamond" case
git-svn-id: trunk@22452 -
that deal with paths/filenames with TPathStr (= ansistring) to prevent
cutting off long paths (no change in speed when compiling the compiler,
1% extra memory usage)
git-svn-id: trunk@21120 -
o support for the new codepage-aware ansistrings in the jvm branch
o empty ansistrings are now always represented by a nil pointer rather than
by an empty string, because an empty string also has a code page which
can confuse code (although this will make ansistrings harder to use
in Java code)
o more string helpers code shared between the general and jvm rtl
o support for indexbyte/word in the jvm rtl (warning: first parameter
is an open array rather than an untyped parameter there, so
indexchar(pcharvar^,10,0) will be equivalent to
indexchar[pcharvar^],10,0) there, which is different from what is
intended; changing it to an untyped parameter wouldn't help though)
o default() support is not yet complete
o calling fpcres is currently broken due to limitations in
sysutils.executeprocess() regarding handling unix quoting and
the compiler using the same command lines for scripts and directly
calling external programs
o compiling the Java compiler currently requires adding ALLOW_WARNINGS=1
to the make command line
git-svn-id: branches/jvmbackend@20887 -
hence contains a dummy "main" that refers to the system unit
FPC_SYSTEMMAIN, which in turn jumps to the main program's PASCALMAIN
* we call FPC_SYSTEMMAIN instead of jumping to it like on Darwin, so that
the TOC gets set correctly
git-svn-id: trunk@20792 -
o don't try to create .class files for generic types
o still generate all JVM-specific wrappers for generic types even though they
won't be written out, because when specializing all the defid's have to
match exactly
o add synthetic routine implementations after generating the specializations,
so that the synthetic routines for those specializations are also generated
(we don't specialize generic versions of the synthetic generic routines
because it's not easy or even always possible to create valid generic
versions of synthetic routines)
o Note: these are Pascal-style generics, not Java-style generics. The generic
types nor their specializations are usable from Java code (specializations
may become usable in the future)
git-svn-id: branches/jvmbackend@19047 -
r18890 | paul | 2011-08-29 16:45:23 +0800 (Пн, 29 авг 2011) | 1 line
compiler: also parse dots in package name and in units which package contains (although package support is not implemented yet in FPC it can parse packages)
------------------------------------------------------------------------
r18886 | paul | 2011-08-29 10:46:13 +0800 (Пн, 29 авг 2011) | 1 line
compiler: replace "string" with ansistring where we concatenate substrings to prevent 255 chars limit overflow
------------------------------------------------------------------------
r18859 | paul | 2011-08-27 11:52:07 +0800 (Сб, 27 авг 2011) | 1 line
compiler: implement delphi like namespaces
git-svn-id: trunk@18911 -
* converts the embedded information into controller specific records (arm and avr)
* new cpu-specific units for several Stellaris (Fury and Tempest class) targets,
+ STM32F103RB
- old Stellaris unit has been removed
git-svn-id: trunk@18848 -
unicodestring = java.lang.String. The reason this was the default in
the past is that this was the first string type that was implemented,
and without it being the default most code involving string operations
would fail. Now the default strings types are the same as for other
targets
+ new {$modeswitch unicodestrings} directive, that when activated
*together* with {$h+},
1) changes char into an alias for widechar
2) changes string into an alias for unicodestring
3) changes the preferred string evaluation type (in case of uncertainty)
to unicodestring
{$modeswitch unicodestrings} with {$h-} does not change anything at all
regarding the string type (it still changes the char type)
+ new uuchar unit that redefines char as widechar, and which is automatically
included by the compiler if {$modeswitch unicodestrings} is enabled
git-svn-id: branches/jvmbackend@18781 -
o every porocedural variable type is represented by a class with one
public "invoke" method whose signature matches the signature of the
procvar
o internally, dispatching happens via java.lang.reflect.Method.invoke().
WARNING: while this allows calling private/protected or other methods
that are normally not accessible from another context, a security
manger can override this. If such a security manager is installed,
most procvars will cause security exceptions
o such dispatching also requires that all arguments are wrapped, but
that's done in the compiler-generated body of the invoke method,
so that procvars can also be called conveniently from Java code
o typecasting between a procedure of object and tmethod is supported,
as well as Delphi-style replacing of only the method pointer via
@procvar1=@procvar2.
o nested procvars are not yet supported, but most of the basic
infrastructure for them is already present
* all units/programs now get an internal __FPC_JVM_Module_Class_Alias$
type when compiled for the JVM target, which is an "external" class
that maps to the unit name. This is required to look up the
JLRMethod instances for regular functions/procedures
+ new tabstractprocdef.copyas() method that allows to create a procvar
from a procdef and vice versa
git-svn-id: branches/jvmbackend@18690 -
* only wrap the init/finalization code after the main program has been
completely processed (pass1, codegen), because this may influence
the required wrapping in case of the JVM target
* replace periods with slashes in the package name when constructing
the classes corresponding to the units (to execute their initialization
code) -- didn't notice this was wrong previously because due to the
incomplete wrapping, they were never being initialized until now
git-svn-id: branches/jvmbackend@18645 -
o moved several routines from pmodules to ngenutil and overrode them
in njvmutil (for unit initialisation tables, resource strings, ...)
o force the evaluation stack size to at least 1 for the main program,
because the unit initialisation triggers are inserted there afterwards
and they require one stack slot
git-svn-id: branches/jvmbackend@18507 -
and initialise global variables that are wrapped (records, arrays)
in those sections
o check whether pd.localst is assigned in dbgjasm, because it's
not for the unit initialisation routine
o moved insertbssdata() from ncgutil to ngenutil and override it
njvmutil (it does nothing in the latter, since global variables
are added as fields to the class representing the unit; the
initialisation is done in gen_initialize_code() in thlcgjvm)
o added force_init() and force_final() methods to ngenutil, so
that targets can force init/final routines separate from the
regular managed types infrastructure (used by JVM for forcing
an init section in case of records/arrays)
git-svn-id: branches/jvmbackend@18460 -
artificially generated stuff rather than directly working with defs/syms
problems
o scanner state saving/restoring, and avoiding problems in case of
errors in the injected strings
o in case of the actual application (adding overriding constructors):
the parameters may be of types not visible in the current unit to
newly written code -> can't just use the scanner...
git-svn-id: branches/jvmbackend@18427 -
since the definition-specific adorning of JVM mangled names is Jasmin-
specific, and such code has no place in symdef
* moved code to adorn JVM mangled names for Jasmin definitions to agjasmin
git-svn-id: branches/jvmbackend@18346 -
whether the mangled name is for defining a symbol, or for referencing
it later (e.g. for a call or load of its address). The reason is that
on the JVM both cases are different.
+ jvmdef unit to encode types according to the JVM rules
+ tprocdef.jvmmangledname() to encode a procdef's JVM mangled name
(the common part of defining/referencing it; tprocdef.mangledname
afterwards adorns it as required)
git-svn-id: branches/jvmbackend@18288 -
* Do not initialize unused symbols, because finalization code is not generated for them either.
* Always initialize/finalize such constants, even if they are declared in {$J-} state and cannot be modified by user code.
git-svn-id: trunk@18121 -
undefined for now as long as
systems_interrupt_table set
defined in systems unit is empty.
This removes several warnings from compiler compilation.
git-svn-id: trunk@17871 -
in Windows, Emx and OS2 targets.
This fixes test failures: test/library/tlib1b.pp and lib2b.pp
link unit TLinker.AddImportSymbol: Added symmangledname parameter.
ogbase unit TImportSymbol.Create: Add AMangledName parameter.
fmodule unit TModule.AddExternalImport: Add symmangledname parameter.
fppu unit: Also put mangled name string for imported symbol.
ppu unit: Increase PPUVersion
utils/ppudump.pp: Adapt to PPU change above.
systems/T_OS units: Use ImportSymbol.MangledName property to create
import libraries or .idata sections.
git-svn-id: trunk@17804 -
- disallow record destructor
- raise internal error for constructor because it is not yet implemented
- handle class constructors and destructors for records
- move find_procdef_bytype to tabstractpointerdef
git-svn-id: branches/paul/extended_records@16544 -
and no language features requiring initialization are used,
do not initialize units, but just configure the fpu and
signal handlers.
git-svn-id: trunk@16124 -
reset_used_unit_defs()/reset_all_defs() calls:
o removed resetting tprocdef.procstarttai/procendtai and
instead check in the debug writers whether the def is
in the current unit or not to determine whether we should
write debug info for it
o use the collected defs in the wpoinfo structure to reset
the wpo flags in the defs, instead of iterating over all
defs in the program and resetting them that way
- removed now unused "is_reset" flag from tmodule
git-svn-id: trunk@15501 -