Difference between revisions of "FPC JVM/Language/ru"

From Free Pascal wiki
Jump to navigationJump to search
Line 24: Line 24:
  
 
Тип ''extended'' приравнен к типу ''double'', точно так же, как и на других платформах, не поддерживающих 80-битовые числа с плавающей точкой.
 
Тип ''extended'' приравнен к типу ''double'', точно так же, как и на других платформах, не поддерживающих 80-битовые числа с плавающей точкой.
 +
 +
=Языковая поддержка=
 +
 +
В связи с разницей между JVM и нативными платформами, не все особенности языка FPC могут быть поддержаны на JVM. Языковая конструкция не указанная ниже, при компиляции в JVM работает точно так же и при обычной компиляции. Однако может возникать некоторая разница в производительности и внутренней реализации.
 +
 +
==Основные конструкции языка==
 +
 +
===Неподдерживаемые конструкции===
 +
* '''Turbo Pascal объекты (objects)''' - поддержка может быть добавлена в будущем, т.к. они очень похожи на структуры (records).
 +
* '''Bitpacking (битовая упаковка)'''- а так же любые преобрзования которые влияют на размещение данных в памяти��({$packset xxx}, {$packrecords xxx}, {$packenum xxx}, ...).
 +
* '''Class helpers''' - Possible to implement, but non-trivial. On the Java side, they would at best only be usable by explicitly calling the methods of these class helpers, since the Java language does not support automatically redirecting method calls from one class to another.
 +
*  '''Variants''' - возможно реализовать, однако их реализация может быть не очень удобной, т.к; ява не поддерживает перегрузку операторов.
 +
* '''Delphi-style RTTI''' - возможно может быть эмулирована.
 +
* '''Resourcestring''' - пока неизвестно насколько трудоёмкая задача по их добавлению.
 +
* '''Вложенные процедурные типы''' - вложенные процедурные типы. В то время как вложенные процедуры и процедурные типы поддерживаются, вложенный-процедурный тип  остаётся не реализованным. Возможно будет добавлен в будущем.
 +
* '''Не локальные goto'''. -  скорее всего никогда не будет реализовано. Теоретически реализовать возможно используя исключения (exceptions) и внутрепроцедурные переходы (goto).
 +
* '''Inline assember''' - пока что нет поддержки ассемблера (Java byte code) для JVM.
 +
* '''Threadvar''' - возможно будет реализовано на базе [http://download.oracle.com/javase/1.5.0/docs/api/java/lang/ThreadLocal.html java.lang.ThreadLocal] переменных.
 +
 +
 +
===Частично поддерживаемые конструкции===
 +
* '''System unit functionality'''. At this time, the system unit is extremely limited and misses support routines for several standard language features (including any kind of input/output, ''val'', ''str'', string helpers other than ''copy'', resource handling, variants). Most such features can still be implemented in the future. The currently supported system routines are ''randomize/random'', ''copy'' (on arrays and strings), ''halt'', ''lo/hi'', ''abs'', ''sqr'', ''odd'', endian swapping routines, ''ror*/rol*/sar*/bsf*/bsr*'', ''upcase/lowercase'', ''runerror''.
 +
* '''Pointers''': it is possible to declare pointer types. It is however only possible to take the address of var/out/constref-parameters and of [[#Implicit_pointer_types]]. Pointer arithmetic is not supported. Indexing pointers ''to non-implicit pointer types'' as arrays is however supported when ''{$modeswitch cs_pointermath}'' is activated. ''FIXME: currently it's always enabled''.
 +
* '''Variant records''': the variant parts of variant records do not overlap in memory, and hence cannot be used to map the same data in different ways. As a result, they also do not save any memory unlike on native targets.
 +
* '''Call-by-reference parameters''' (var/out/constref): the JVM does not support call-by-reference, nor taking the address of a local variable. For [[#Implicit_pointer_types]], this is no problem since there the compiler always has a pointer to the actual data available. For other types, call-by-reference is emulated by the compiler via copy-in/copy-out, which means that changes are not immediately visible outside the called routine. The steps followed by the compiler are:
 +
** construct an array of one element
 +
** store the parameter value in the array (in case of var/constref)
 +
** pass the array to the called routine
 +
** the routine can change the value in the array
 +
** on return, the potentially changed value is copied out of the array back into the original variable (in case of var/out)
 +
* '''Untyped const/var/out parameters'''. These are supported in the same way as they are in Delphi.NET, see http://hallvards.blogspot.com/2007/10/dn4dp24-net-vs-win32-untyped-parameters.html (with the same limitations as regular var/out parameters on the JVM target)
 +
* '''Include files'''. While include files will work fine at compile time, the Java class file format does not support referring to more than one source file. As a result, the compiler will only insert debugging line information for code in the main unit file. This limitation may be resolved in the future through the use of SMAP files as described in http://jcp.org/aboutJava/communityprocess/final/jsr045/index.html
 +
* '''Resources'''. Currently, files specified in '''{$r xxx}''' directives will be copied without any further processing into a jar file with the same name as the program, under the directory ''org/freepascal/rawresources''. If you add this jar file to the Java class path when executing the program, you can load the resource files using the JDK's built-in resource file helpers (see ''java.lang.Class.getResource()'' and ''java.lang.Class.getResourceAsStream()''). Delphi-style resource support may be (partially) added in the future.
 +
* '''Unit initialization code'''. If a unit is used from an FPC-compiled program, then the unit initialization code will be run on startup. If the main program is a Java program, then the unit initialization code will only run when the first method is entered that accesses a global constant or variable or calls a global procedure/function from that unit. Note: using classes, types or class variables from a unit does '''not''' by itself trigger executing the unit's initialzation code. If you wish to manually trigger this, you can do so by adding a statement such as ''Object dummy = new unitName();'' to your Java code.

Revision as of 19:35, 21 August 2011

English (en) русский (ru)

Общая информация

Поддержка JVM это пока лишь изменения в компиляторе. А это значит, что портирован только модуль System и модули которые импортируют лишь некоторые JDK классы. Другие RTL модули не доступны. Функционал модуля System так же очень ограничен (подробности ниже).

Со временем, вполне возможно реализовать большинство стандартных модулей RTL таким образом, чтобы они компилировались для JVM платформы. Но это не является целью и баг-репорты о том что какого-то модуля не хватает - особой пользы не принесут. (Но конечно, патчи приветствуются!)

Компиляция в JVM код на данный момент довольно медленная. Причина - используемый Ява ассемблер Jasmin - медленный. И причина не в том, что сам ассемблер написан на Java, а просто потому что он так написан.

Минимальная требуемая версия JDK для программ скомпилированных FPC - 1.5.

Терминология и соглашения

  • on the Pascal side/on the Java side: refers to code written in resp. Pascal or Java. A number of features are only available when programming in Pascal, because the Java language has no similar concept.
  • неявные указатели - некоторые типы, которые не являются указателями в Паскале, на уровне Ява реализованы как классы или массивы. Что делает их неявными указателями на данные, т.к. и Ява-массивы и классы - указатели. Возможно это и не очевидно, но переменные такого типа, как раз можно заставить действовать, точно так же как и на нативных платформах, чем переменные каких-либо других типов.
  • полное имя класса - на данный момент компилятор не поддерживает пространство имён (такие как "org.freepascal" или "java.lang") как элемент синтаксиса. Точно так же имена модулей с точками не поддерживаются. Это означает что нельзя в качестве имён использовать строки вроде "java.lang.Object". Все Паскаль-заголовки для импортированных Ява-модулей используют аббревиатуру имени класса, используя первые буквы из имени каждого пакета, и заканчиваясь именем класса. Например "Java.lang.Object" - в паскале объявлен как "JLObject". Для типов объявленых в паскаль-исходниках синтаксис "имя_модуля.определитель" - работает как ожидается. Тем не менее, для всех определителей описанных ниже, будут указаны их полное имя Ява-класса, т.к. получить паскаль имя от ява-класса достаточно просто, обратное действие практически невозможно.

Базовое поведение платформы

По устройству компилятора платформа Java/JVM рассматривается как 32-битная. Это лишь означает, что вся арифметика ориентируется, по умолчанию, на 32-бита, а не 64. Точно так же, как и на нативных платформах, созданный код будет без проблем запускаться и на 64-битных ява-машинах. Компилятор так же будет использовать 64-битные инструкции (опкоды) для 64-битных вычислений.

Причина такого выбора:

  • 32-битна арифметика выполняется эффективнее, чем 64-битная;
  • Индексы в JVM массивах всегда 32-битные;

Тип extended приравнен к типу double, точно так же, как и на других платформах, не поддерживающих 80-битовые числа с плавающей точкой.

Языковая поддержка

В связи с разницей между JVM и нативными платформами, не все особенности языка FPC могут быть поддержаны на JVM. Языковая конструкция не указанная ниже, при компиляции в JVM работает точно так же и при обычной компиляции. Однако может возникать некоторая разница в производительности и внутренней реализации.

Основные конструкции языка

Неподдерживаемые конструкции

  • Turbo Pascal объекты (objects) - поддержка может быть добавлена в будущем, т.к. они очень похожи на структуры (records).
  • Bitpacking (битовая упаковка)- а так же любые преобрзования которые влияют на размещение данных в памяти��({$packset xxx}, {$packrecords xxx}, {$packenum xxx}, ...).
  • Class helpers - Possible to implement, but non-trivial. On the Java side, they would at best only be usable by explicitly calling the methods of these class helpers, since the Java language does not support automatically redirecting method calls from one class to another.
  • Variants - возможно реализовать, однако их реализация может быть не очень удобной, т.к; ява не поддерживает перегрузку операторов.
  • Delphi-style RTTI - возможно может быть эмулирована.
  • Resourcestring - пока неизвестно насколько трудоёмкая задача по их добавлению.
  • Вложенные процедурные типы - вложенные процедурные типы. В то время как вложенные процедуры и процедурные типы поддерживаются, вложенный-процедурный тип остаётся не реализованным. Возможно будет добавлен в будущем.
  • Не локальные goto. - скорее всего никогда не будет реализовано. Теоретически реализовать возможно используя исключения (exceptions) и внутрепроцедурные переходы (goto).
  • Inline assember - пока что нет поддержки ассемблера (Java byte code) для JVM.
  • Threadvar - возможно будет реализовано на базе java.lang.ThreadLocal переменных.


Частично поддерживаемые конструкции

  • System unit functionality. At this time, the system unit is extremely limited and misses support routines for several standard language features (including any kind of input/output, val, str, string helpers other than copy, resource handling, variants). Most such features can still be implemented in the future. The currently supported system routines are randomize/random, copy (on arrays and strings), halt, lo/hi, abs, sqr, odd, endian swapping routines, ror*/rol*/sar*/bsf*/bsr*, upcase/lowercase, runerror.
  • Pointers: it is possible to declare pointer types. It is however only possible to take the address of var/out/constref-parameters and of #Implicit_pointer_types. Pointer arithmetic is not supported. Indexing pointers to non-implicit pointer types as arrays is however supported when {$modeswitch cs_pointermath} is activated. FIXME: currently it's always enabled.
  • Variant records: the variant parts of variant records do not overlap in memory, and hence cannot be used to map the same data in different ways. As a result, they also do not save any memory unlike on native targets.
  • Call-by-reference parameters (var/out/constref): the JVM does not support call-by-reference, nor taking the address of a local variable. For #Implicit_pointer_types, this is no problem since there the compiler always has a pointer to the actual data available. For other types, call-by-reference is emulated by the compiler via copy-in/copy-out, which means that changes are not immediately visible outside the called routine. The steps followed by the compiler are:
    • construct an array of one element
    • store the parameter value in the array (in case of var/constref)
    • pass the array to the called routine
    • the routine can change the value in the array
    • on return, the potentially changed value is copied out of the array back into the original variable (in case of var/out)
  • Untyped const/var/out parameters. These are supported in the same way as they are in Delphi.NET, see http://hallvards.blogspot.com/2007/10/dn4dp24-net-vs-win32-untyped-parameters.html (with the same limitations as regular var/out parameters on the JVM target)
  • Include files. While include files will work fine at compile time, the Java class file format does not support referring to more than one source file. As a result, the compiler will only insert debugging line information for code in the main unit file. This limitation may be resolved in the future through the use of SMAP files as described in http://jcp.org/aboutJava/communityprocess/final/jsr045/index.html
  • Resources. Currently, files specified in {$r xxx} directives will be copied without any further processing into a jar file with the same name as the program, under the directory org/freepascal/rawresources. If you add this jar file to the Java class path when executing the program, you can load the resource files using the JDK's built-in resource file helpers (see java.lang.Class.getResource() and java.lang.Class.getResourceAsStream()). Delphi-style resource support may be (partially) added in the future.
  • Unit initialization code. If a unit is used from an FPC-compiled program, then the unit initialization code will be run on startup. If the main program is a Java program, then the unit initialization code will only run when the first method is entered that accesses a global constant or variable or calls a global procedure/function from that unit. Note: using classes, types or class variables from a unit does not by itself trigger executing the unit's initialzation code. If you wish to manually trigger this, you can do so by adding a statement such as Object dummy = new unitName(); to your Java code.