Smart Mobile Studio
  • News
  • Forums
  • Download
  • Store
  • Showcases
    • Featured demos
    • The Smart Contest 2013, Round 1 – Graphics
  • Documentation
    • Get the book
    • System requirements
    • Prerequisites
    • Getting started
      • Introduction
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • Themes and styles
    • Project types
      • Visual project
      • Game project
      • Console project
    • Layout manager
    • Networking
      • TW3HttpRequest
      • TW3JSONP
      • Loading files
  • About

Compiler options explained

Posted on 09.04.2016 by Smart Mobile Studio Team Posted in Developers log, News and articles 1 Comment

CompilerOptionsIn the forums there was a post about a detailed description of the compiler options. Since there are currently no in-depth information available this post tries to clarify the topic a bit.

Let’s first start with the basic compiler options as can be seen in the screenshot below:

Basic Compiler Options

Compiler Options 1

Unter ‘Compiler Options’ the user can adjust the internal DWScript compiler, which is responsible for compiling the Object Pascal source code into an internal representation. While the DWScript compiler offers a few more options, these are the only ones the user can play with.

Assertions

If ‘Assertions’ is checked statements like Assert(BoolExpression) will be compiled. If you’re not familiar with asserts, just think of them as additional stability checks you can add every here and there. They are translated to something like:

if not BoolExpression then
  raise EAssertionFailed.Create('Assertion failed');

where the Boolean experession can be something like “SomeValue < AnotherValue” or a function call like “IsValueValid(SomeValue)”.

As soon as any assertion appears in your source code the following lines will be added to your JavaScript source code:

var EAssertionFailed={
  $ClassName: "EAssertionFailed",
  $Parent: Exception,
  $Init: Exception.$Init
}
function $Assert(b,m,z) { if (!b) throw Exception.Create($New(EAssertionFailed),"Assertion failed"+z+((m=="")?"":" : ")+m); }

If you uncheck this option, the entire statement will be replaced by /* null */ in the JavaScript source code. If you call a function in that expression, it won’t be called at all. So be careful to only put checks in an assertion.

Optimization

If ‘Optimization’ is checked the internal coOptimize is passed to the DWScript. This triggers several countless optimizations in the DWScript compiler. A detailed list of what this influences is yet missing, but in general it tries to omit empty statements or eliminate dead code. Here’s a brief list of what is done

  • removes empty initialization/finalization blocks
  • optimizes const assignments (not active in some versions)
  • optimizes function expressions (e.g. constant functions -> constants)
  • optimize comparisons (constant comparison is done at compile-time)
  • …

It adds another pass to the compilation, which results in longer compilation times.

NOTE: At the time of writing it seems as if this option is not taken into account (even if enabled) in Smart Mobile Studio due to an improper setup. It will be fixed as soon as possible.

Hints

With ‘Hints’ several options about the hinting level of the compiler are available. If set to ‘Disabled’ no hints will be shown in the compiler message list. If set to ‘Normal’ the usual hints are emitted. Even more hints are emited with ‘Strict’ and in ‘Pedantic’ it will even complain differences in case sensitivity. The latter can be in particular useful if interfacing the case sensitive JavaScript language.

Predefined Conditions

The predefined conditions are nothing more than a convenient way to specify some compiler definitions. These correspond to:

  • Handle uncaught exceptions -> {$DEFINE SMART_INTERNAL_HANDLE_EXCEPTIONS}
  • Automatically refresh in the browser -> {$DEFINE SMART_INTERNAL_AUTO_REFRESH}
  • Legacy support for IE9 (and below) -> {$DEFINE SMART_LEGACY_INTERNET_EXPLORER}

and will be set at a compiler level (for all units).

In addition the linker will output a file called ‘timestamp.txt’ if the ‘Automatically refresh in the browser’ is checked. This will be used to identify if the file has been changed.

Custom conditional defines

In addition to the predefined conditions you can specify custom conditional defines. These will add to the compiler and similar to the predefined conditions set at the compiler level (i.E. set in all units).

 

Code Generation

Previously the DWScript compiler options were described. This section now covers the code generation options. These correspond to the DWScript JSCodeGen, which was to some point available as open source. As it hasn’t evolved much in regards of the basic options, you can still find it around if you need more details.

Code Generation

The ‘Code Generation’ section is combined with the ‘Runtime Checks’ section. The latter sits in between the compiler and the code generation as it adds runtime checks at compile time, which are then transpiled to JavaScript.

Inline Magic

With inline magic the compiler will inline the DWScript’s mini RTL functions: AnsiLowerCase, AnsiUpperCase, ArcCos, ArcSin, ArcTan, ArcTan2, Ceil, Cos, Copy, MidStr, Exp, FloatToStr, Floor, Format, HexToInt, Infinity, IntPower, IntToHex, IntToStr, IsFinite, IsNaN, LeftStr, Ln, LowerCase, Max, Min, MaxInt, MinInt, NaN, Pi, Pos, PosEx, Power, Round, Sign, Sin, Sqr, Sqrt, StrBeginsWith, StrDeleteLeft, StrContains, StrFind, StrJoin, StrMatches, StrSplit, StrToFloat, StrToInt, SubStr, SubString, Tan, TypeOf, Unsigned32, UpperCase, VarIsNull, VarIsClear and VarIsArray with direct JS code instead of call them as functions.

This typically speeds up the application as typically less code is generated.

 

Emit RTTI information

With ‘Emit RTTI information’ the compiler will output RTTI information. It can be left unchecked if no RTTI is needed.

 

Ignore published in implementation

No information available so far.

 

De-virtualization

Often methods are declared as virtual, but there is no override used in the source code. In this case it might make sense to unmark it as virtual to improve its performance upon calls. Since it is cumbersome to maintain by hand (especially if overrides are planned to be implemented in the future) and sometimes difficult (if an overrided function doesn’t call the inherited function) to find, this feature de-virtualizes your code.

The feature takes time to perform, but might result in a major boost if enough de-virtualize opportunities exist (ie. if virtual methods are not called directly or indirectly in initialization sections or constructors)

 

Emit source locations

This controls whether source locations are emitted or not. This feature links to the verbosity options.

 

Smart linking

Checks if the function is used at all. If not, it is not generated at all.

As a dedicated stage in the code generation process this takes time, but it might be well worth it. In order to work decently, the units shouldn’t have much cross-dependencies.

NOTE: This feature still contains a bug for functions that are only called from within a lambda statement.

 

Code packing

If enabled the code will be packed by stripping empty lines. It is marked as recommended, especially for a release.

 

Code obfuscation

If enabled the code will be obfuscated by replacing the function names with strings from a random generator. This will make deciphering of the JS source code much harder.

It is marked as recommended, especially for a release, when it is important to protect your source. If you want others to read your code, you should of course uncheck this option.

NOTE: Class names will not be obfuscated as RTTI or other functions such as comparing the ClassName won’t work. This is important to know as this can be the reason why tools like Google’s closure compiler might not work as expected although it does similar techniques like obfuscation.

 

Use main body

If ‘Use main body’ is checked the entire code is wrapped into a main function by the compiler. This might or might not necessary depending on the context where you want to use the script. For example the default HTML template already adds another main body, so it might not be needed.

A ‘main body’ in this context means:

var $Application = function() {
  // your code will appear here
}
$Application();

Especially for environments where less is more (e.g. microcontroller programming), this just adds an unnecessary overhead.

 

Verbosity

With ‘Verbosity’ the verbosity of the generated JavaScript code can be controlled. If set to ‘None’, the JavaScript output will not contain any comments that link to the original Object Pascal source. With ‘Normal’ it will contain comments with the function names and position in the original source code. And with ‘Verbose’ it will contain even more comments (about the classes etc.).

 

Runtime checks

If checked the code generation will add several runtime checks. JavaScript itself is not very critical so eventually an access beyond the bounds might just create a new field you are not aware of.

For example the code below will compile and run without complains.

var MyArray: array [0 .. 1] of Integer;
for var Index := 0 to 9 do
  MyArray[Index] := Index;

As can be seen easily the code is not doing right as the array index clearly exceeds the range of elements. This would result in a hidden issue that can be very hard to locate. With ‘range checking’ enabled, an exception is raised, which points you to the location in the source code where the range is exceeded.

NOTE: Due to a bug in the, range checking does not work with the code below when the array is allocated dynamically:

var MyArray: array of Integer;
MyArray.SetLength(2);
for var Index := 0 to 9 do
  MyArray[Index] := Index;

This bug will hopefully be fixed in one of the next versions.

Other runtime checks include

  • Instance checking
  • Condition checking
  • Loop step checking

At the time of writing several issues in the IDE could be revealed. These will (hopefully) be fixed and the article will be revised in the future.

This also includes items that are not yet described perfectly clear in this article.

Compiler options
« It’s finally here – Smart Mobile Studio 2.2
Smart Mobile Studio 2.2 Hotfix 1 »

One thought on “Compiler options explained”

  1. CWBudde says:
    12.04.2016 at 12:55

    The bug mentioned at the end of the article (about dynamic arrays being not properly checked) will be fixed with the next hotfix.

Comments are closed.

Pages

  • About
  • Feature Matrix
  • Forums
  • News
  • Release History
  • Download
  • Showcases
    • The Smart Contest 2013, Round 1 – Graphics
  • Store
  • Documentation
    • Creating your own controls
    • Debugging, exceptions and error handling
    • Differences between Delphi and Smart
    • Get the book
    • Getting started
      • Introduction
      • Local storage, session storage and global storage
      • Application architecture
      • The application object
      • Forms and navigation
      • Message dialogs
      • pmSmart Box Model
      • Themes and styles
    • Layout manager
    • Networking
      • Loading files
      • TW3HttpRequest
      • TW3JSONP
    • Prerequisites
    • Real data, talking to sqLite
    • System requirements
    • Project types
      • Visual project
      • Game project
      • Console project

Archives

  • December 2019
  • December 2018
  • November 2018
  • July 2018
  • June 2018
  • February 2018
  • September 2017
  • April 2017
  • November 2016
  • October 2016
  • September 2016
  • April 2016
  • March 2016
  • January 2016
  • October 2015
  • September 2015
  • July 2015
  • April 2015
  • January 2015
  • December 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • November 2011
  • October 2011
  • September 2011

Categories

  • Announcements (25)
  • Developers log (119)
  • Documentation (26)
  • News (104)
  • News and articles (16)

WordPress

  • Register
  • Log in
  • WordPress

Subscribe

  • Entries (RSS)
  • Comments (RSS)
© Optimale Systemer AS