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

Asm sections? You betcha!

Posted on 28.11.2011 by Jon Lennart Posted in Developers log 6 Comments
OP4JS about to go Alpha

OP4JS about to go Alpha

I posted a picture of the OP4JS pre-Alpha testbed to my Facebook group, and a member found it interesting that it had an ASM section in the code. How can there be an ASM section in a system that targets JavaScript you wonder?

Well, assembler for OP4JS is basically what assembler would be to a real Delphi application. In this case: raw JavaScript. Eric Grange, my friend and author of our compiler, has done a great job on transposing classical Object Pascal terminology onto the (let’s face it) bewildering typology of JavaScript.

Take this simple procedure for instance:

procedure TMyObject.Testing;
var
  mRef: TObject;
begin
  mRef := tagRef;
  asm
    (@mRef).style.width=100 + "px";
  end;
end;

What we do here is to first get a handle to the our tag (the tagRef is a public property of TW3TagObject, the class TW3CustomControl inherits from). We then enter the ASM section, use that reference to access and alter the width style property. Ofcourse you dont have to deal with this stuff unless you want to, because OP4JS will ship with a rich set of controls ready to be used. And rolling your own controls is so simple it’s almost ridicules.

The squiglies

But why the @ prefix you wonder? Well, when we obfuscate our code (make it unreadable, or less “stealable” for the average hacker), all the names of variables and methods are altered. As such, the compiler needs to be able to quickly figure out if you are using a JS based variable or an Object Pascal variable. So all Object Pascal variables have to be prefixed with the @ character. Due to the nature of Javascript you also need to isolate direct references to object fields and native fields inside ( [ .. ] ) sections, like in this example:

asm
  (@self.FWidth) = parseInt( (@mRef).style.width );
end;

Where did my pointers go?

JavaScript don’t have pointers, at least not in the proper sense of addresses and memory buffers. What it does have are object references and data references (it also has a weak reference counted garbage collector). So under OP4JS we dont have a type called “pointer” because it would screw up the reality of compiling to JavaScript. Instead, TObject serves the function of a universal object reference, and variant serves as a universal data reference. Variants are special however, because we dont have any operators dealing with it directly (so you cant write: A:=1 + someVariant). The variant type is just used to transport data from one method to another.

But, all the standard types are there: string, boolean, float, integer and so on. You also have records, interfaces and enumerations to play with. It really is a neat system once you get the hang of it.

  function getSomeData: Variant;
  begin
    asm
      /* return a data structure */
      @result = {first:"hello",second:"hello2"}
    end;
  end;

  procedure handleSomeData(aValue: Variant);
  begin
    asm
      /* access the data structure passed in */
      alert(@aValue.first); //will show "hello"
    end;
  end;

Super simple custom control

To demonstrate how extremely simple it is to create your own controls under OP4JS, let’s make a scroll-text. As you probably know HTML have a tag called marquee that scrolls text in a variety of ways. It has been called an evil tag because it consumes a lot of CPU speed (and that part is very true), but just for the hell of it – let’s make a super-simple OP4JS version of it:


unit myscroller;

interface

uses w3system, w3components;

type

TW3Marquee = Class(TW3CustomControl)
private
  FText:    String;
  procedure SetText(aValue:String);
public
  Property  Text:String read FText write SetText;
End;

implementation

procedure TW3Marquee.SetText(aValue:String);
Begin
  //Keep the text
  Ftext:=aValue;

  // Cheat and inject the tag into our innerHTML
  // This works because TCustomControl has already created
  // a tag for us. So we just inject the content
  innerHtml:='<marquee style="'
  + 'font-family: verdana;'
  + 'width: 100%;'
  + 'height: 100%;'
  + '-webkit-marquee-increment:3px;'
  + '-webkit-marquee-speed:fast;'
  + '-webkit-marquee-direction:backwards;'
  + '-webkit-marquee-repetition:infinite;'
  + '">' + FText + '</marquee>';
end;

end.

Naturally this is just a quick example. A fully functional and quality control would have a slightly different layout. There we would isolate the marquee in it’s own tag object. But the approach is perfectly valid, although a bit slap-dash 🙂

OP4JS does not work by injecting text into the DOM, that is to slow. We create tag objects via the Javascript API and access our objects by reference. This is why OP4JS apps are much faster than those produced by other JS compilers. We try to avoid the use of getElementById() because it results in poor performance.

« Console and gaming applications under OP4JS
OP4JS: Project file format »

6 thoughts on “Asm sections? You betcha!”

  1. gabr says:
    28.11.2011 at 21:08

    Is capitalization of setText in TWarquee3M required to start with a small letter or is this just chosen to better reflect the usual JavaScript usage?

  2. Jørn E. Angeltveit says:
    29.11.2011 at 10:11

    It’s just like Delphi/Object Pascal. Not case sensitive. So you may call it SetText, settext, SETTEXT or whatever.

  3. A. Bouchez says:
    29.11.2011 at 16:43

    In handleSomeData procedure, could you use aValue.First in object pascal code (not asm/Javascript block)? I.e. is there any kind of late-binding for this variant type?

    • Jon Lennart Aasenden says:
      30.11.2011 at 04:48

      In short, no. But in a “real” example you would just use normal records for this.

      Type
      TMyRecord = Record
      first: string;
      second: string;
      End;

      function getSomeData:TMyRecord;
      Begin
      result.first := ‘hello’;
      result.second:=’hello2′;
      end;

      You know..normal delphi stuff.

      Variant is not a type you use much, like i mentioned it’s more for transportation of JS structures than it is values (but you can use it if you like, but we dont have compiler operators for it).

    • Jon Lennart Aasenden says:
      30.11.2011 at 04:56

      But one neat trick is this:

      type
      TMyRecord = Record
      first,second:String;
      End;

      procedure TForm1.Test;
      var
      mData: TMyRecord;
      Begin
      asm
      (@mData).first = “from js”;
      (@mData).second = ” its all good”;
      end;
      w3_alert(mData.first + mdata.second);
      end;

      There is no difference between our records, and a typed javascript record. This opens up enourmous potential when dealing with server-side technology and client side dependencies (i.e native JS libs).

      • A. Bouchez says:
        30.11.2011 at 14:08

        This is why I’m interested a lot about op4js for a pure object pascal coding on the AJAX client side using our little Client-Server mORMot framework.
        Our objects will be defined as plain classes, so we’ll be able to access from it with strong-typing.
        I was just wondering about late-binding possibility with variant in op4js scripts. But it is not a mandatory

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