Difference between revisions of "Porting from FPC/Delphi to pas2js"

From Free Pascal wiki
Jump to navigationJump to search
(Created page with "This page contains useful tips for Delphians and FPC users on how to port code to pas2js. =Numbers= * Internally all numbers are ''double'' * There is '''no''' ''Int64'' and...")
 
(→‎Details: fix URL [the file has been removed in commit D748BB6630DD628F6EE6859C60B4B373693EEB20 though])
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This page contains useful tips for Delphians and FPC users on how to port code to pas2js.
+
This page is for Delphians and FPC porting code to pas2js. It contains useful tips and common traps.
  
 
=Numbers=
 
=Numbers=
  
* Internally all numbers are ''double''
+
* Internally all numbers are ''double''. Therefore integers range from -9,007,199,254,740,991 to 9,007,199,254,740,991, so about 1/1024th of a 64bit value.
* There is '''no''' ''Int64'' and no ''QWord''
+
* There is '''no''' ''Int64'' and no ''QWord''.
 
* All '''bitwise operators are limited to 32bit''', including the ''mod'' operator, which is limited to signed 32bit.
 
* All '''bitwise operators are limited to 32bit''', including the ''mod'' operator, which is limited to signed 32bit.
 
* '''Integers overflows''' at runtime differ from Delphi/FPC. For example adding ''var i: byte = 200; ... i:=i+100;''' will result in ''i=300'' instead of ''i=44'' as in Delphi/FPC. When range checking ''{$R+}'' is enabled ''i:=300'' will raise an ''ERangeError''.
 
* '''Integers overflows''' at runtime differ from Delphi/FPC. For example adding ''var i: byte = 200; ... i:=i+100;''' will result in ''i=300'' instead of ''i=44'' as in Delphi/FPC. When range checking ''{$R+}'' is enabled ''i:=300'' will raise an ''ERangeError''.
 +
* '''Division by zero''' does not raise ''EDivByZero'', instead it results in ''NaN''.
 +
* '''Currency''' has only 54 bits. Currency is internally a double, multiplied by 10000 and truncated. The below values are the safe limits, within every step exists. Since currency is a double it can take much larger values, but the result may differ from Delphi/FPC:
 +
** MaxCurrency =  900719925474.0991; // fpc: 922337203685477.5807;
 +
** MinCurrency = -900719925474.0991; // fpc: -922337203685477.5808;
  
 
=Strings=
 
=Strings=
Line 16: Line 20:
  
 
JavaScript enforces an absolute async manner of programming:
 
JavaScript enforces an absolute async manner of programming:
*Many calls are asynchronous and return immediately, like loading a resource.
+
*Many calls are asynchronous and return immediately. For example loading a resource.
 
*There is '''no''' Application.ProcessMessages. You cannot wait till some event occurs. You must set an event. That's why anonymous functions are so frequently used in JS - they keep the local variables accessible.
 
*There is '''no''' Application.ProcessMessages. You cannot wait till some event occurs. You must set an event. That's why anonymous functions are so frequently used in JS - they keep the local variables accessible.
*There is no multithreading, no shared memory. Many browsers/JS engines allow to start workers, but that is more like processes than threads.
+
*There is no multithreading, no shared memory. Many browsers/JS engines support webworkers, but that is more like processes than threads.
 +
 
 +
=Details=
 +
 
 +
A more detailed list can be found in the {{gitlab|repository|FPC|3.3.1/utils/pas2js/docs/translation.html|translation.html}}.file in the sources.
 +
[[Category:Pas2js]]

Latest revision as of 21:41, 8 March 2023

This page is for Delphians and FPC porting code to pas2js. It contains useful tips and common traps.

Numbers

  • Internally all numbers are double. Therefore integers range from -9,007,199,254,740,991 to 9,007,199,254,740,991, so about 1/1024th of a 64bit value.
  • There is no Int64 and no QWord.
  • All bitwise operators are limited to 32bit, including the mod operator, which is limited to signed 32bit.
  • Integers overflows' at runtime differ from Delphi/FPC. For example adding var i: byte = 200; ... i:=i+100; will result in i=300 instead of i=44 as in Delphi/FPC. When range checking {$R+} is enabled i:=300 will raise an ERangeError.
  • Division by zero does not raise EDivByZero, instead it results in NaN.
  • Currency has only 54 bits. Currency is internally a double, multiplied by 10000 and truncated. The below values are the safe limits, within every step exists. Since currency is a double it can take much larger values, but the result may differ from Delphi/FPC:
    • MaxCurrency = 900719925474.0991; // fpc: 922337203685477.5807;
    • MinCurrency = -900719925474.0991; // fpc: -922337203685477.5808;

Strings

  • String is UnicodeString and there are no other string types.
  • Strings are immutable in JS. That means changing a single character creates a new string. That's why some fast Delphi/FPC string functions are much slower in pas2js.

Asynchronous vs Waiting

JavaScript enforces an absolute async manner of programming:

  • Many calls are asynchronous and return immediately. For example loading a resource.
  • There is no Application.ProcessMessages. You cannot wait till some event occurs. You must set an event. That's why anonymous functions are so frequently used in JS - they keep the local variables accessible.
  • There is no multithreading, no shared memory. Many browsers/JS engines support webworkers, but that is more like processes than threads.

Details

A more detailed list can be found in the translation.html.file in the sources.