Sign in Join
Wiki copytemporary

FPC JVM/Language

English · Русский

General information

This is a compiler-only port. That means that except for the system unit and a unit that imports the JDK classes, no other standard RTL or other units are available. Furthermore, even the system unit is quite limited in terms of the functionality that it provides (details are below).

Over time, it is possible to implement most of the standard RTL and other unit functionality in a way that it can be compiled using the JVM-targeted compiler. That is however not the goal of this initial port and bug reports about missing unit-level functionality are not useful at this point (but patches are of course welcome! :).

Compiling code for the JVM target is currently quite slow. The reason is that the used Java assembler, Jasmin, is very slow. The reason is probably not so much that it is written in Java, but simply that it is quite a slow program.

The minimum JDK version required for running programs generated by the FPC JVM port is 1.5.

Used terminology and conventions

Base platform behaviour

Internally the Java/JVM target is treated by the compiler as a 32 bit target. This only means that arithmetic expressions are by default evaluated using 32 bit arithmetic, rather than by 64 bit arithmetic, just like for native 32 bit targets. The generated code will still run perfectly on 64 bit JVMs, and the compiler will also use the built-in 64 bit arithmetic opcodes of the JVM when performing 64 bit computations.

Reasons for this choice include:

The extended floating point type maps to double , just like it does on other targets that do not support native 80 bits floating point support.

Language feature support

While the language supported by the JVM port is as close as possible to the one supported for native FPC targets, there are some differences due to the nature of the JVM platform. Any language feature not mentioned below can be expected to behave the same as it does on native FPC targets (except for accidental omissions). This behaviour is only guaranteed at the purely semantic level, and not in any way in terms of absolute or relative performance.

General language features information

Unsupported language features

Partially supported language features

New language features

pascal
type
    JavaClassName = class [external ['package.name'] [name 'ExternalClassName']] [(JavaSuperClassName|InterfaceName [, InterfaceName, InterfaceName])] 
    [strict][private, protected, public]
     [variables declarations]
     [method declarations]
    end;

Overloading

A number of different Pascal types and parameter passing conventions map to the same type signature in the JVM. The reason is that the JVM supports less primitive types than Pascal, and because some parameter passing constructs have to be emulated using other types.

This means that certain overloads that are valid for native targets are invalid when targeting the JVM, because the internal method name has to encode the parameter types on that target. The compiler will detect such situations and print an error when they occur.

Cases that you may encounter include:

Specific language features information

Classes

Classes are implemented as Java classes:

Issues to take into account when using FPC-defined classes from Java code:

pascal
type
    TMyClass = class
    constructor Create(l: longint); virtual;
    end;

becomes

pascal
class TMyClass {
    TMyClass(int l) {
    ...
    }
    
    // the generic parameter declaration means "any class reference
    // type for TMyClass or one of its descendants")
    static TMyClass Create(java.lang.Class<? extends TMyClass> self, int l)
    {
    ...
    }

Interfaces

Interfaces are implemented as Java interfaces:

Implicit pointer types

As mentioned in the #Used_terminology_and_conventions, certain types that are not pointer-based in the Pascal language are implemented on top of Java classes or arrays. These data structures are pointers in Java, and as a result we can do some things with them that we cannot do with other types that map more directly onto a Java type.

The implicit pointer types and their corresponding Java representations are listed below:

Specific properties of implicit pointer types are:

Strings

String, unicodestring and java.lang.String

The JVM internally only supports a 16 bit unicodestring type (java.lang.String). For this reason, unicodestring is generally somewhat more efficient than either ansistring or shortstring on the JVM target.

A unicodestring directly maps to the java.lang.String type. This means that if your code is supposed to be called from Java code, all public string parameters and constants should be unicodestring rather than some other string type.

In order to facilitate this process, a new {$modeswitch unicodestrings} has been added to the compiler. If used together with {$h+} , it will make uncodestring the default string type and widechar the default char type. This is similar to the change in Delphi 2009, except that it is available via a modeswitch rather than forced onto all code.

If {$modeswitch unicodestrings} is used with {$h-} , then the default string type will be shortstring but the default char type will remain widechar. Notice that {$h+} is the default for {$mode delphi}.

Ansistring and shortstring code page

The "ansi" code page is set by the java program on startup. A default code page is chosen based on the environment on Linux and Windows. On Mac OS X, for legacy reasons the default code page is always MacRoman , which almost never is what you really want to use. See the Usage instructions for details on how to specify the default code page.

String conversions

The compiler will implicitly convert any string type to java.lang.String and vice versa.

Type aliases and subrange types

The JVM supports neither type aliases nor subrange types. As a result, none of the marked type definitions in the following example will be visible to Java code. Of course, they still work as expected in Pascal code.

<syntaxhighlight lang=pascal> type

pascal
tc = class
     end;
pascal
tenum = (ea,eb,ec);
pascal
tc2 = tc;         // Pascal-only
     intsub = 3..41;   // Pascal-only
     enumsub = eb..ec; // Pascal-only

</source>

Using JDK functionality

The JVM port of FPC includes a Java utility called javapp. It is based on the source code of the standard JDK program javap , which can be used to print the contents of a Java .class file.

The javapp utility can be used to create Pascal headers for compiled Java classes. The system unit contains the subset of the standard JDK classes that is required to implement standard language functionality. The rest of the standard classes that are part of the JDK 1.5 are available via the jdk15 unit. It includes all JDK classes from the java. , javax. and org.* hierarchies. Other classes from the JDK are not exported because they are platform-specific and/or can change between different JDK versions.

Some things to watch out for:

Run java -jar javapp.jar -help to see usage information.

Using Android SDK functionality

The principle is the same as with the JDK, except that the javapp utility cannot fully automatically translate the Android SDK class hierarchy due to a circular class reference, a bug related to constants called create , and the use of an inner class. The FPC RTL for the Android/JVM target however includes a unit called androidr14 in which those problems are manually resolved. It contains header translations for all classes in R14 of the Android SDK (corresponds to Android 4.0) from the java. , javax. , org. , junit. and android. hierarchies.

Issues to watch out for


From the Free Pascal wiki, page "FPC JVM/Language", as the Internet Archive kept it on 2022-12-31, last changed on 2020-02-16. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 3, last changed by WikiArchive .

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.