Download

Go here to download ready-to-run and source distributions of Jangaroo. more...

Saturday, January 28, 2012

Simulating ActionScript Parameter Default Values in JavaScript

To continue our series on simulating ActionScript language features in JavaScript, this episode is about parameter default values.
In contrast to JavaScript, ActionScript allows to specify a default value for a function (or method) parameter, like so:

 1 public function insult(s = "fool") {
 2   return "you " + s;
 3 }

The idea is that when the method is called without providing a value for parameter s, the default value "fool" will be used. Details on what additional rules hold for declaring parameter default values are given in the Adobe documentation on function parameters and a bit less reference-like e.g. in a tutorial on Ntt.CC.

Why, it's easy, isn't it?
A straight-forward implementation in JavaScript (similar to the solution suggested by Bernd Paradies for FalconJS) would be to replace undefined paramter values by their default value:

 1 function insult(s) {
     if (s === undefined) {
       s = "fool";
     }
 2   return "you " + s;
 3 }

(We could now start a discussion on whether it shouldn't be
     if (typeof s === "undefined") {
because in JavaScript, undefined may be redefined, but anybody who does so is, excuse me, a fool.)
In JavaScript, when you omit a parameter when calling a function, the parameter value indeed is undefined. But it is a fallacy to assume that every undefined parameter must be replaced by its default value! Consider the following ActionScript class:

 1 public class DefaultParameterTest {
 2
 3   public function DefaultParameterTest() {
 4     trace("1. " +  insult ("nerd"));
 5     trace("2. " +  insult ());
 6     trace("3. " +  insult (undefined));
 7   }
 8
 9   public function insult(s = "fool") {
10     return "you " + s;
11   }
12 }

What do you think will be traced? Try it out, and you'll see that explicitly handing in undefined does not trigger the default value! Thus, the result is
1. you nerd
2. you fool
3. you undefined

(Careful, never call a JavaScript programmer "you undefined"!)
Using the straight-forward JavaScript implementation, the result would be
1. you nerd
2. you fool
3. you fool

As you can see, using parameter default values depends on the number of formal arguments, not on their value. This is the reason why they are also called optional parameters, and why after a parameter with a default value, all following parameters must also specify a default value.

Getting it right
Thus, the correct JavaScript equivalent (as generated by the Jangaroo compiler jooc) is to check the number of formal parameters. Fortunately, this can be realized by checking arguments.length:

 1 function insult(s) {
     if (arguments.length < 1) {
       s = "fool";
     }
 2   return "you " + s;
 3 }

In fact, this solution even provides better runtime performance when using multiple optional parameters, since multiple arguments.length checks can be nested, while the undefined checks in the straight-forward solution would be sequential. Consider the following example:

 1 public function foo(p1, p2, p3 = 3, p4 = 4) {
 2   return p1 + p2 + p3 + p4;
 3 }

The JavaScript fragment generated by Jangaroo looks like so:

 1 function foo(p1, p2, p3, p4) {
     if (arguments.length < 4) {
       if (arguments.length < 3) {
         p3 = 3;
       }
       p4 = 4;
     }
 2   return p1 + p2 + p3 + p4;
 3 }

Jangaroo even optimizes undefined default values, since left out actual parameters are undefined in JavaScript, anyway.

Alternative Solutions
We also thought of using a switch statement, generating code like the following:

 1 function foo(p1, p2, p3, p4) {
     switch (arguments.length) {
       case 0:
       case 1:
       case 2:
         p3 = 3;
         // fall through
       case 3:
         p4 = 4;
     }
 2   return p1 + p2 + p3 + p4;
 3 }

At first sight, this solution seems more efficient, because arguments.length is only evaluated once. The reason why we still chose the nested if code layout is that the switch solution becomes either long or non-robust when using many non-optional parameters. Note the lines case 0: and case 1: in the example above: although the method should never be called with less than two parameters (since the first two are not optional), we want to handle that case, too, since Jangaroo code may be called from JavaScript, where no function signature check is performed. When the function is called with fewer parameters than required, you would still expect the default values to pop in. So the case statements would pile up when there are many non-optional parameters. However, I could imagine a mixed solution like the following:

 1 function foo(p1, p2, p3, p4) {
     switch (arguments.length < 2 ? 2 : arguments.length) {
       case 2:
         p3 = 3;
         // fall through
       case 3:
         p4 = 4;
     }
 2   return p1 + p2 + p3 + p4;
 3 }

The most intelligent solution would be to dynamically decide whether the prior length check pays off against adding several case statements. I guess I'll add that to the Jangaroo backlog!

Tuesday, December 6, 2011

Simulating ActionScript in JavaScript: Private Members Cont'd

In the first blog post about simulating private members in ActionScript, I compared different solutions to represent private members in JavaScript. The solution implemented by Jangaroo is to rename private members, so that they do not name-clash with private members of the same class, defined on a different inheritance level.
Bernd Paradies asked how Jangaroo solves untyped access to private members. Since the answer is rather extensive, I'll dedicate this follow-up post to the topic.

The short answer is: it's the nature of the beast. Untyped access to private members cannot be detected at compile time. However, potential access to private members can be detected at compile time and generate code that repeats the check at runtime, although Jangaroo does not implement this at the moment.

Typed Private Member Access
Let's recall the typical way to access private members, which can easily be detected by the Jangaroo compiler:

 1 public class Foo {
 2   private var foo:String = "bar";
 3   public function getFoo():String {
 4     return foo;
 5   }
 6 }

As foo in line 4 is resolved to a field of the class, and there is no implicit this access in JavaScript, the Jangaroo compiler adds this. before foo. Also, as field foo is declared private, the compiler renames it to foo$1 (see previous blog post) and thus generates the following JavaScript code for the body of method getFoo():

 4     return this.foo$1;

Where is My Type?
Now consider the following code (which does not really make sense, but illustrates the point):

 1 public class Foo {
 2   private var foo:String = "bar";
 3   public function getFoo():String {
 4     var untypedThis:Object = this;
 5     return untypedThis.foo;
 6   }
 7 }

Of course, in this simple example it would still be possible to determine the runtime type of untypedThis statically, but it is easy to imagine a situation where this is not possible. In the current Jangaroo implementation, the following JavaScript code would be generated for the body of method getFoo():

 4     var untypedThis = this;
 5     return untypedThis.foo;

As you can see, the compiler fails to detect that foo actually refers to the private member, does not rename the access to foo$1, and thus the undefined value of untypedThis.foo would be returned.

A (partial) solution is to let the compiler detect any expression of the form untyped.private-member and generate code that takes into account the runtime type of untyped, like so:

 5     return untyped[untyped instanceof Foo ? 'foo$1' : 'foo'];

Trusting today's JavaScript JIT compilers' optimizations, this code should be moved to a utility function to avoid double evaluation of the untyped expression (which could have side effects):

 5     return Foo.$class.get(untyped, 'foo');
 
where Foo.$class provides access to Jangaroo's "meta class" of Foo, and get() would be implemented there like this:

  public function get(object:Object, property:String):* {
    return object[object instanceof this.publicConstructor ?
      property + this.inheritanceLevel : property];
  }

The Weak and the Wicked
Looking at ActionScript carefully, you'll notice that the identifier or expression left of the dot does not even have to be untyped, but may just be typed with a more general type, and the same scenario may apply. For example, assume our class Foo is a subclass of dynamic class Bar, we could replace Object by Bar, and the example would still work! Even if Bar is not dynamic, we could access the private member foo through a local variable of type Bar using square brackets, like so:

public class Foo extends Bar {
  private var foo:String = "bar";
  public function getFoo():String {
    var weaklyTypedThis:Bar = this;
    return weaklyTypedThis['foo'];
  }
}

The Flex compiler does not complain, and at runtime, in Flash, indeed the private member is accessed. Compare this to the following example, where we try to access the private member of a superclass:

public class Baz extends Foo {
  public function Baz() {
    super();
    var superThis:Foo = this;
    trace(superThis['foo']); // is undefined, not "bar"!
  }
}

Maybe you'll be surprised that the result is not any kind of access violation, but simply undefined—the private member of the superclass is simply not visible for the subclass! This is well emulated by Jangaroo through renaming private members. The Jangaroo compiler just has to take care to detect every correct access of a private member and rename the property upon access.

Turing Strikes Again
Things get even nastier when the property is a dynamic expression. Consider

  return this[veryComplicatedComputation()];

Here, too, we'd have to generate

  return Foo.$class.get(this, veryComplicatedComputation());

and extend the utility function by a runtime check whether the property is actually a private member name:

  public function get(object:Object, property:String):* {
    return object[object instanceof this.publicConstructor &&
      this.getMemberDeclaration("private", property) ?
        property + this.inheritanceLevel : property];
  }

Summary
Taken together, the important criterion when to generate code for possible private member access is not whether the left-hand expression of the dot is untyped, but the compiler has to check whether the complete property access is not typed. This is the case exactly when the property is not a compile-time constant or when the property cannot be resolved statically within the type of the expression, and in any case, the type of the expression must be a supertype of the current class or the current class itself.

To wrap up, the compiler would have to generate a call to the dynamic access function if and only if
  1. the left-hand expression could have a runtime type compatible to the current class and 
  2. the property expression could be one of the current class's private members.
Here, could means that it may be, but is not certain at compile time. If both conditions are certain at compile time, the compiler knows for sure that the code represents access to a private member, and can simply use the renamed property.

One more thing: I have been talking about read access of private members. The same strategy would have to be applied when writing members, resulting in another utility function set(object, property, value).

Optimize?
Of course, we could optimize runtime performance by using specific utility functions for the following three different cases:
  1. The property is definitely a private member, but the left-hand expression may or may not be of the current class: check instanceof only.
  2. The left-hand expression is definitely of the current class, but the property may or may not be a private member: check the property only.
  3. Both the left-hand expression may or may not be of the current class, and the property may or may not be a private member: check instanceof and the property.
However, my guess is that this optimization is not necessary. Firstly, checking instanceof and whether some string is contained in a fixed and not very large set are cheap operations. Secondly, when using ActionScript (and not untyped JavaScript), you should avoid untyped access of properties whenever possible. Thus, the situation is a rare case, and would only be implemented for full ActionScript semantic compatibility. If the developer wants better performance, she can either insert a type cast to convert the property access to a typed one, or move dynamic properties to a dedicated object whose type is statically incompatible with the current class (e.g. use Dictionary), and thus no runtime check would be generated.
If this solution proves to inflict significant runtime overhead, the compiler should issue a warning when it has to generate runtime checks.

Wednesday, November 30, 2011

Simulating ActionScript in JavaScript: Private Members

Inspired by Adobe's Bernd Paradies, member of the FalconJS / FlashRT team, blogging about his ideas on "Compiling ActionScript to JavaScript", I thought it was about time to give more details about how Jangaroo implements ActionScript language features. Because there are so many of them, blogging about them one at a time seems like a good idea. Let's start with "private members".

The Early Days
When people started simulating class-based OOP in JavaScript, many thought that it is not possible to define private members that support the principle of information hiding, because in JavaScript, all properties of an object are publicly accessible. So in many cases, the convention was used to let private members start with an underscore ("_"), meaning "don't use this member, best assume it is not existing at all".

The Reference Solution
As we all know in the meantime, it is possible to implement real information hiding in JavaScript, namely by using closures / lexical scoping. Douglas Crockford (who else?) has written a nice summary of this approach back in 2001: Private Members in JavaScript
So it looks like all we have to do to simulate ActionScript's private members in JavaScript is to use this pattern, right? Of course, it is not that easy, as in practice, there are two problems with private members à la Crockford:
  1. Runtime overhead
  2. Source-code placement
While the first is a general problem, the second is Jangaroo-specific.
The runtime overhead of closures results from the fact that in Crockford's solution, private members and privileged methods (methods that use private members) have to be defined inside the constructor. This means that the corresponding function objects are created for every instance of the class! This results in a performance penalty as well as in increased memory usage. Of course, this is not an issue for classes with few instances (extreme: singletons), but for classes like events, where you create many, many instances, this can quickly become a major problem.
The second problem, source-code placement, results from a specific Jangaroo feature. In debug mode, the Jangaroo compiler generates JavaScript code that keeps every piece of executable code at exactly the same line as in the ActionScript source file. This is a central feature of Jangaroo and very important for source-level debugging with a free choice of JavaScript debugger. So how can we place private and privileged methods inside the constructor, when in the ActionScript source code, they are not?

The Super-Secret Private This
For solving the source-code placement issue, I came up with the idea of a "shared private this" object. It turned out that this approach makes things a bit more complicated and only mitigates (but not removes) the runtime overhead, so it did not actually make it into Jangaroo, but still I'd like to present it here.
The basic idea is that private members, as opposed to being local variables in constructor scope, are properties of a single object that is defined inside the constructor. To be shared, this "private this" object has to be "injected" into, i.e. put in the surrounding lexical scope of every privileged method. Consider the following class, which is the ActionScript version of the example used by Douglas Crockford:

 1 public class Container {
 2   public var member:String;
 3   private var secret:int;

 4
 5   public function Container(param:String) {
 6     member = param;

 7     secret = 3;
 8   }
 9
10   public function stamp(string:String):String {
11     return member + string;
12   }
13
14   private function dec():Boolean {
15     if (secret > 0) {
16       secret -= 1;
17       return true;
18     } else {
19       return false;
20     }
21   }
22
23   public function service():String {
24     return dec() ? member : null;
25   }
26 }
To inject the "private this" into all privileged methods, we wrap these inside functions. What Douglas calls that, we'll call this$, and all other helper idenfiers are suffixed with $. Here is the resulting JavaScript code:

 1 Container = (function() {
 2   //public var member:String;
 3   //private var secret:int;
 4
 5   var Container = function(param) { var this$ = init$(this);
 6     this.member = param;
 7     this$.secret = 3;
 8   };
 9
10   Container.prototype.stamp = function(string) {
11     return this.member + string;
12   };
13
14   var dec = function() {
15     if (this.secret > 0) {
16       this.secret -= 1;
17       return true;
18     } else {
19       return false;
20     }
21   };
22
23   var service$ = function(this$){return function(){
24     return this$.dec() ? this.member : null;
25   };};
26
27   var init$ = function(o) {
28     var this$ =
{
29       dec: dec
30     };

31     o.service = service$(this$);
32     return this$;
33   }
34
35   return Container;
36 })();
Note how all executable code stays in exactly the same line, and how similar it can be expressed in JavaScript!
The following variants of Douglas' patterns were used:
  • Private methods are only defined once (reduces runtime overhead!), and are supposed to be called on the "private this". If they need to access public members, too, we could easily extend the "private this" by a reference to the "public this".
  • Privileged methods are wrapped in a function that receives the "private this", so that the current "private this" is in lexical scope. 
  • To keep all source code at its original location, all additional initialization is moved to a generated method init$. It creates the "private this" this$ with all private members, creates instances of privileged methods handing in this$, and assigns these to the "public this".

The Pragmatic Solution
As said above, this solution still introduces runtime overhead and a bit complexity, so we looked for a more efficient and simpler alternative. I mentioned the naive approach to use a simple naming convention. The real flaw in this approach is not that you can access "private" members when you should not be able to. When compiling ActionScript to JavaScript, we can check access rights on the ActionScript source, so this is not an issue. But what this approach breaks is that private members are also used to avoid name clashes between subclass and superclass!
Image you define a framework, and provide some base class that is supposed to be extended by clients of the framework. This base class usually provides members with different visibility. The private members (and the "internal" ones, which we neglect for now) can not be seen by a subclass. A client's subclass could define its own private members any way they like, as long as they don't name-clash with public or protected members of the superclass.
Now you update the framework and add a private method, as you think this should not change the framework API. But if we use the naive naming convention of prefixing all private members with an underscore (or the like), there is now the chance that the new private member of the superclass name-clashes with an existing private member of the client's subclass!
Jangaroo's pragmatic solution to separate private members of different inheritance levels within one class is to suffix private member names with a $ followed by the numeric inheritance level. Object has inheritance level 0, and a class extending X has the inheritance level of X plus one. This effectively prevents name-clashes between private members of the same name, but defined on different inheritance levels, and thus solves the framework update problem described above.
We used to compute the inheritance level of a class at runtime, but this made class loading and initialization more complex. Thus, we later decided to let the compiler compute the inheritance level. Of course this reduces "binary" compatibility, meaning that when you refactor a framework class e.g. by introducing an intermediate class in the inheritance hierarchy, clients will have to recompile their code, or the inheritance level of their subclass will be incorrect. But recompiling (without changing the source code) after updating a framework should not really be a problem.
To give a concrete example, here is the simplified generated JavaScript code for the example above. It is not exactly what Jangaroo would produce, as there are many other features covered by the Jangaroo Runtime, which I'll elaborate on in upcoming blog posts. Also, it does not illustrate the inheritance issue, but just imagine a subclass that also defines a private field secret, which would then be renamed secret$2.
 1 Container = (function() {
 2   //public var member:String;
 3   //private var secret:int;
 4
 5   var Container = function(param) {
 6     this.member = param;
 7     this.secret$1 = 3;
 8   };
 9
10   Container.prototype.stamp = function(string) {
11     return this.member + string;
12   };
13
14   Container.prototype.dec$1 = function() {
15     if (this.secret$1 > 0) {
16       this.secret$1 -= 1;
17       return true;
18     } else {
19       return false;
20     }
21   };
22
23   Container.prototype.service = function() {
24     return this.dec$1() ? this.member : null;
25   };
26
27  
return Container;
28 })();
Wrap-Up
Let me conclude with an overview of the four solutions for private members in JavaScript discussed here.
naive naming convention private members
(D. Crockford)
private this inheritance level suffix
(used in Jangaroo)
information hiding
avoiding name-clashes
no runtime overhead
keep source lines
As you can see in the table, there is no perfect solution (no column with checkmarks in every row), so for Jangaroo, we chose the pragmatic one that ensures good performance, while having some drawbacks on information hiding.

Outlook
Since performance is the only argument against the "private this" solution, we should investigate in performance analysis of today's JavaScript engines to quantify the time and space overhead introduced by the appoach. Maybe it is not that bad after all.
With all modern browsers supporting the JavaScript API Object.defineProperty(),we can improve Jangaroo's pragmatic solution's information hiding by defining all private members to not be enumerable. Taking a closer look at ActionScript semantics, actually, all class members are not enumerable, i.e. they are all not visible in a for ... in loop (only dynamic properties are).
There are several possible improvements to approximate ActionScript semantics more closely when relying on features of a modern JavaScript engine (ECMAScript 5). I'll come to these when discussing further ActionScript language features.

Thursday, November 10, 2011

Enterprise JavaScript with Jangaroo at PLASTIC / SPLASH 2011

While almost one year ago, we talked about "Jangaroo - AS3 w/o FlashPlayer", we thought it was about time to stress the other story, namely using Jangaroo for creating large-scale JavaScript applications. Because that's what we do very successfully at CoreMedia.
Several people (thanks Florian, Martin!) pointed us at a very fitting call for papers of the PLASTIC workshop at the SPLASH 2011. It is about Programming Languages And Systems Technologies for Internet Clients, with a focus on "compilation and runtime techniques for Internet client programming languages". Andreas kicked off the paper, Olaf and Dennis supported with proof-reading, LaTeX support and helpful comments, and I fleshed out the text and extended the parts of my expertise, namely the runtime, libraries, and build process. The paper, entitled Enterprise JavaScript with Jangaroo --
Using ActionScript 3 for JavaScript ”Programming in the Large”
, was accepted and can be downloaded here.
On 24th of October, I presented the corresponding talk at the PLASTIC workshop in Portland, Oregon. To not bore the part of the audience who already read the paper (maybe the empty set?), the slides show a third category of "how to execute another programming language in the browser", since providing a client-side interpreter seems to be a hot topic (mostly because of Google swiffy, but there are others, too). But have a look at the slides for yourself.
Before starting with the slides, I showed off the demos Box2D and Open Flash Charts, which I admit are a bit off-topic, since they rather belong to the "port Flash applications to HTML5" story than to "Enterprise JavaScript", but hey, they are always good to get people's attention ;-).
I hope I could get across what Jangaroo is able to, and got some interesting feedback. Adam Welc (Co-Chair of the workshop, in his other life working on Flash at Adobe) pointed me to another Flash-related Open Source projects, lightspark, which might help in getting on with Jangaroo's Flash re-implementation JooFlash.
People liked the way Jangaroo keeps the generated code close to the source, even keeping line numbers to allow source-level debugging.
The most motivating part when visiting a workshop or conference is of course about meeting people. I remembered Google's Mark Miller from the Ajax Experience 2009 in Boston, who here at PLASTIC co-authored a paper about traits.js: recommended read! Christian Hammer, Andreas Gampe, Aiman Erbad and several others also presented and we had interesting discussions. Was nice getting to know you guys!
Another JavaScript guru I also met first on Ajax Experience is Rik Arends, then at ajax.org, who now does a wonderful job over at Cloud9IDE. I tell you he's one of the good guys (even if we disagree on where to use typed languages and compilers)!
Finally, I loved the key note of David Ungar, Everything You Know (about Parallel Programming) Is Wrong! A Wild Screed about the Future; he really is a great presenter! Using Romeo and Juliet as an example of parallel actions that went wrong (and might have ended up "hunky-dory" in a different sequentialization) is really funky...

Friday, November 26, 2010

Jangaroo at FlashCodersNY

Tyler Larson of FlashCodesNY asked us whether we'd be interested to present and discuss Jangaroo on one of their weekly meetings in Manhatten. The event took place on Wednesday 17th of November in Manhattan, while Andreas and I were connected via live streaming from Hamburg. Well, our time zone offset is not really ideal for meetings in the late afternoon in New York, but with lots of coffee and adrenaline, we hopefully managed to give an exciting presentation of what Flash coders can do with Jangaroo.
After showing some general slides about Jangaroo, we went right into coding with the brand new Jangaroo version 0.7.12. Using IntelliJ IDEA 9 as the cockpit for development, we showed how to import and build a Jangaroo Maven project. Examples of Jangaroo-Flash projects were the well-known Box2DFlashAS3 Jangaroo port and a Jangaroo version of AS3 Lemmings.
Most attendees liked the idea of being able to deploy Flash applications to the browser without a FlashPlayer plugin. However, they were also concerned about performance especially on mobile devices (iOS JavaScript and canvas performance currently only suffices for quite simple applications) and API completeness, correctness and compatibility. One feedback concerning missing AS3 features in Jangaroo was that against our previous assumption, some developers like and use E4X quite a lot. Also better support for annotations is important for using certain Flash/Flex libraries, e.g. FlexUnit 4.

To run Flash code directly in the browser, Jangaroo not only has to compile ActionScript 3 to JavaScript, but also all Flash APIs have to be re-implemented. While the documentation is under a Creative Commons license and can be reused, the implementation is not open. One central feature of Flash are the graphics, which can be emulated in the browser by using HTML5's canvas. Our library "jooflash" does exactly that. This is a big effort.We challanged all FlashCodersNY and of course any other Flash coder enthusiastic about Open Source to contribute to the jooflash library. jooflash is available on github, so please go ahead, fork, code, and do a pull request!
In the session, there were many in-depth questions about how to debug Jangaroo code, how to use other IDEs, and many more, which indicated great interest in the technology.
For example, one very interesting new topic was whether multiple embedded Jangaroo "Flash objects" on the same page are possible and how they behave. The answer is yes, you can run many Jangaroo applications on the same page. Usually, all code is loaded directly into the page, leading to shared classes, but also to shared static variables. If this is not what you want, simply load each application in an iframe. A more elegant solution that shares code, but not state, would require changes in the Jangaroo Runtime.

Although only virtually present, we felt really welcome and were quite amused when we were asked the final question: "When was the last time you stayed up until 3 o'clock in the morning?"
Thanks FlashCodersNY, it was worth it!

Monday, November 22, 2010

Jangaroo 0.7.12: More AS3 Features, even for IE9

What's new in Jangaroo 0.7.12?

We are proud to present our latest Jangaroo release with many improvements and new features in several different areas.
Our last blog post is a while ago, but in the meantime, we delivered several intermediate releases and used light-weight Twitter announces (just follow @Jangaroo).

General

  • github
    Jangaroo is on github now!
    Check out Jangaroo Tools (compiler, Maven plugins, IDEA plugin) from https://github.com/CoreMedia/jangaroo-tools.
    Find Jangaroo JavaScript wrapper APIs (browser API, Ext JS, CKEditor, soundmanager 2) and libraries (URI utils, JooUnit, JooFlash) at https://github.com/CoreMedia/jangaroo-libs.
  • Maven Central
    Since version 0.7.9 you can use Jangaroo from Maven without specifying any <repository> or <pluginRepository> now, so the POMs get even simpler. This is possible because all new Jangaroo Maven artifacts are deployed to Maven Central. Sonatype kindly offers this service to all Open Source projects. The old Jangaroo Maven repository still exists to host the old versions.
  • Compiler and Runtime Version in Generated Code
    The compiler now adds version information, so that the Jangaroo Runtime can check compatibility of generated JavaScript code. A class runtimeApiVersion/compilerVersion is compatible with the current Runtime if

    • the runtimeApiVersion matches the Runtime's runtimeApiVersion exactly and
    • the compilerVersion is lower or the same as the Runtime's compilerVersion.
    The idea is that runtimeApiVersion is only incremented when the contract between compiler and runtime changes. Thus, you may use library code compiled with an older compiler together with a runtime plus your code compiled with a later compiler. This may be important if you want to use a library and a new compiler feature, but the library is not yet available compiled with the latest compiler version. As long as we release all Jangaroo libraries ourselves, this may be academic, but this situation is bound to change sooner or later.
  • Cyclic Static Dependency Detection
    The Runtime now logs a warning if a cyclic static initializer dependency is detected. This happens if one class triggers initializing another class and the other class directly or indirectly triggers initializing the first class, which is already in progress. This situation does not have to cause problems, but the first class is already used while it is not yet fully initialized, so e.g. members might still be "undefined". Clean code should not contain such initialization cycles.
  • IntelliJ IDEA 9 Plugin
    As always, the Jangaroo Language IDEA plugin has been updated to use the latest compiler. In IDEA, simply go to Settings | Plugins | Available, search for Jangaroo Language, and click the "Download & Install" or "Update Plugin" button. After restarting IDEA, you can import Jangaroo Maven projects and enjoy code completion, fast compile-and-deploy turn-around ("Make Project"), and instant static type checking.

Newly Supported AS3 Features


  • Full trace() Compatibility and More
    In previous Jangaroo versions, trace() only took a single parameter to print to the JavaScript console. However, in AS3, trace takes arbitrary parameters and joins them to a string (using space as separator). We now implement exactly this method signature and semantics.
    To also take advantage of Firebug's different console log levels, indicated through icons, without changing the method signature, we use the following convention: If you start your trace output with one of [LOG], [INFO], [WARN] or [ERROR], the corresponding Firebug console method (log(), info(), warn() or error()) is invoked with the remainder of the message. For other environments, the string is printed as-is.
  • Variable Default Values
    Depending on their type, class variables (fields) are initialized to standard values as defined in the AS3 language specification (see bottom of page). Note that this feature is only implemented for class variables, including statics, but not yet for local variables.
  • Helper Classes
    Out-of-package helper classes, i.e. non-public class definitions contained in the source file of a public class, are now fully supported. Unfortunately, I could not find any official Adobe reference documentation on helper classes, so please refer e.g. to this blog post on helper classes .
  • Annotations
    Basic support for annotations, i.e. meta data in square brackets added to classes or methods, has been added to the Jangaroo compiler and runtime. Since we do not yet fully implement flash.utils.describeType(), the only way to query meta data at runtime is through a Jangaroo-specific API which is subject to change. If you want to give it a try, find the meta data for a class using the following code:
    var metadata:Object =
      joo.SystemClassDeclaration(SomeClass['$class']).metadata;
    
    To retrieve the metadata of a public class member, use the following pattern:
    var memberMetadata:Object =
      joo.SystemClassDeclaration(SomeClass['$class'])
      .getMemberDeclaration("public", "someMember").metadata;
    
    In both cases, the according annotation is transformed to an Object straight-forwardly, e.g.
    [SWF(width=465, height=465,
         backgroundColor=0, frameRate=15)]
    
    results in the metadata object
    {SWF:{width:465, height:465,
          backgroundColor:0, frameRate:15}}
    
  • as Operator
    Jangaroo has been supporting as for quite some time, but so far, it was not transformed into any code (only comments in debug mode).
    Now, as is implemented with its original AS3 semantics, i.e. checking the object's type and evaluating to null if there is no match. Be aware that this changes semantics of your code, for example if you used as to cast to a type to call some method, which might have worked at runtime without the object actually being an instance of the type. In such cases, you can fall back to the type cast syntax (Type(expr)), which still generates comments only. Be warned that this code might someday throw a TypeError when using a later Jangaroo release.

Browser Compatibility


  • trace() in IE
    trace() now also works with Internet Explorer's console. It already worked before with Firefox with Firebug, WebKit, Opera, and any browser using Firebug light.
  • Property Accessor Functions in IE9
    So far, Jangaroo supported AS3 properties (function get/set) in WebKit, Firefox and Opera, but not in any version of Internet Explorer. IE9 is the first to implement custom properties accessor functions for any JavaScript object. IE8 already introduced the ECMAScript 5 methods to define properties, but they were only implemented for DOM objects. Thus, Jangaroo only supports property accessor functions in IE9.
    To simulate this feature also in older IE versions is a much harder task, but still we might tackle it later (see discussion on Jangaroo User Group).
  • Workaround for IE9 Crash
    Jangaroo stores class meta data under the expando property $class of the class's constructor function. Even for built-in classes, when used from Jangaroo code, the Runtime attaches this property. So far, this approach worked well with IE, but IE9 beta crashed (!) when trying to run our Box2D demo.
    After intensive debugging, I figured out that IE9 does not like the $class property of built-in class TypeError being accessed. With some more digging into, the real source revealed itself: If in IE9 document mode, you set any expando property on the built-in Error class and query it through a subclass (like TypeError), IE9 beta crashes. Comprising only 21 characters, this might actually be the shortest JavaScript "code of death" for IE9:
    Error.x=1;TypeError.x
    
    The workaround for Jangaroo is not to set $class on the Error class, but Microsoft will have to fix this bug anyway, or there will be lots of Websites with links that say: "To crash IE9, please click here."
  • @-Properties in IE
    Respect that IE does not like properties starting with @, and quote them.

Bug Fixes, Improvements and API Changes

  • fixed a minor bug in regular expressions syntax and improved parser error messages
  • improved class initialization, which was sometimes triggered eagerly when not necessary
  • cleaned up Runtime logging in debug mode: log class initialization instead of class loading
  • Introduced joo.boundMethod() in favor of Function.prototype.bind(). See its ASDoc for details.
  • overhauled joo.ResourceBundleAwareClassLoader API. See its ASDoc for details.

Jangaroo Libraries

Together with a new release of the Jangaroo tools, we always release all Jangaroo libraries, too. Besides being recompiled with the latest compiler version, there are also many updates and new features.
  • Flash Compatibility jooflash
    This library re-implements the Flash APIs in the browser, using HTML5 features like canvas. It is still rather incomplete, but nevertheless suffices for demos like flash-lines as well as quite complex applications like Box2DFlashAS3.
  • Network Utilities jangaroo-net
    This new module contains utilities for URI parsing, formatting, relativizing and resolving functionality according to RFC 3986.
  • Ext JS ActionScript API ext-as
    The library Ext AS is an ActionScript 3 wrapper for Ext JS 3.2.2, so you can do Ext coding with code completion and type checks while keeping a fast turn-around.
  • Many more libraries, which we will cover in a future blog post.

As always, comments, questions, corrections, praise etc. are highly welcome! Why not contribute by issuing pull requests on github to include your bug fixes?

Andreas and Frank

Monday, August 9, 2010

Jangaroo 0.7.0 Released

In the latest release, Jangaroo features Runtime optimizations, localization, and semicolon insertion.

Jangaroo Runtime without with

After concentrating on compiler and build process in release 0.6, the new release 0.7 cleans up the Jangaroo Runtime accordingly.
Many features that used to be implemented in the Runtime became obsolete, because the compiler now takes care of them:
  • The mapping of private member names now consists of a set of local variable assignments, generated by the compiler. The runtime merely still contributes the class inheritance level, which can only be computed at runtime if we want to keep "binary" update compatibility with libraries. This removed the last with-statement from the generated code! Since with is considered harmful, we are proud to now avoid it completely. This results in less ambigous code ("where the heck does that $foobar variable come from?") and most likely in better performance, since modern JavaScript engines with their just-in-time compilers have better chances to perform optimizations without with.
  • Resolving unqualified identifiers (usually class names without package) is no longer done at runtime, but completely at compile time. Even implicit imports, i.e. usages of classes of the same package or the top level package, are detected and made explicit by the compiler. Thus, the runtime no longer has to deal with imports. It still needs to know which other classes to load (i.e. its dependencies). We may re-introduce more concise code for imported classes later.

New Feature: Localization Support

Localization means to provide your software with different texts and configuration, depending on the user's locale settings. For Jangaroo, this means that there should be some standard way to access the current user's locale and that the runtime should be able to load differnet resources depending on that user locale. Since the Runtime can already load classes automatically, representing resource bundles as classes suggests itself. To help you creating such classes, there is a new tool, the Properties Compiler. Actually, it has been included with the Jangaroo tools for quite some time as a hidden feature. But after we have revamped it with the 0.7 release, we're glad no-one (but ourselves) has used it yet ;-). The properties compiler takes a set of properties files for different locales, in Java often called a resource bundle, and generates an ActionScript class for each locale, and one for the defaults. We will add an example to the Jangaroo website soon, also explaining how to let a user choose her locale.

Automatic Semicolon Insertion

The Jangaroo compiler jooc is now capable of inserting semicolons according to the ECMA-262 specification (of which ActionScript 3 is an implementation). For compiler writers: this is done by exploting the error recovery mechanism of the CUP LALR(1) parser generator.
We implemented this feature not beause we like it so much, but to increase our ActionScript 3 compatibility, esp. for the purpose of porting 'legacy' code. For example, we needed to patch the FlexUnit library at many places just because some semicolon was missing. These patches are now no longer necessary.
When writing new code, you should not use the optional-semicolon feature of ActionScript 3, as recommended by Adobe in the Flex SDK coding conventions and best practices.
Semicolon Insertion is considered one of the bad parts of JavaScript, and ActionScript 3 inherited them: a line terminator might trigger semicolon insertion which might change the meaning of the program in unexpected ways. Because of these bad vibes, we added a compiler switch which configures the behaviour of jooc with regard to semicolon insertion. The syntax is -autosemicolon mode, and possible modes are:
  • warn (which is the default) will issue a compiler warning if a line terminator is the cause for semicolon insertion
  • error will treat this as an error (some kind of strict mode, recommended setting). 
  • quirks silently inserts all these semicolons as JavaScript interpreters and Flex compc do (good luck with this setting!)
Note that the ECMA-262 rule which inserts a missing semicolon right before a closing brace ('}') is unaffected by this switch. This rule basically states that a semicolon is optional at the end of a block, which we consider a favourable thing.
One last tip: IntelliJ IDEA offers a code style setting for ActionScript to highlight unterminated statements. Just open Settings - Project Settings - Code Style - JavasScript/ECMAScript/ActionScript and place a checkmark at Use semicolons to terminate statements.

Frank and Andreas

P.S.: As always, we updated the Jangaroo IDEA plugins Jangaroo Language and Jangaroo EXML (containing the properties compiler) to the new version.