Opening The Blackbox

The Flash Player is to many of us developers a blackbox. We use it every day in our job but do not really know much about it. Of course we do not have to understand its inner workings but it is sometimes very interesting to know more a little bit about specific implementation details.

Continue reading ‘Opening The Blackbox’

How JITB converts ActionScript to Java

One of the biggest challenges when writing a program like JITB is to convert ActionScript to Java. There are major differences between ActionScript 3.0 and Java 1.6 which JITB currently targets.

ActionScript 3.0 is a dynamically typed language with function closures. Furthermore it has native XML support, scope-changes, implicit getters and setters etc. The main issue however is to convert the set of bytecodes ahead of time to statically typed Java code. JITB does not know anything about what is going on since it compiles all the code ahead of time.

Continue reading ‘How JITB converts ActionScript to Java’

JITB’s PixelBender support

I have demoed support for PixelBender shaders in JITB at the FOTB 2010 conference. It turned out that JITB can run PixelBender code really fast and well. I have demoed a Julia and Terrain raytracer which were both kindly contributed by David Lenaerts. I only showed the demos since I would have been running out of time. I still owe you an explanation of how it all works.
Continue reading ‘JITB’s PixelBender support’

Disappointment No. 3

I created a couple of programs like AS3doc and AS3V. Both have never really gotten any adoption because I canceled their development. The reason was that Adobe shortly before or after I finished my tool released a competitive tool. Given the fact that I work fulltime on audiotool.com it is hard for me to find some time off to develop those applications. Some of them are even not written for myself — like the FlexMojos code coverage.

However it happened again. I write a tool that is not even fully released yet and there comes Adobe around the corner with something that must have been in development for a while. Enough time to tell us that we can decide if we want to continue working on it or not.

I have no problem with Adobe developing such products. In fact I second that they have a Flex QA team which develops tools like FlexPMD and the recent coverage plug-in. However the way this process happens really frustrates me. Why would I want to work on something that Adobe is already developing somewhere silently and release it without giving anyone notice? But they do not owe me an explanation for what they do. It would also be arrogant to say that I demand to know upfront.

I am just sad that there is no dialog at all. This happened three times now. I will not continue doing this.

That does not mean I will stop working on Apparat and JITB. Only no more enterprise releated open source software.

PixelBender Support In Apparat

Since PixelBender is becomming a more popular technology in the Flash ecosystem I decided to add first-class Apparat support for it.

As you might know I have done a couple of different tools for PixelBender already.

When I switched to Linux a while ago I had to discover that there is no compiler for PixelBender available and also no PixelBender toolkit. Even PBDT does not work on Linux since it requires a compiler.

In the current state Apparat can read and write PBJ files. I already implemented the format two years ago for the outline view plug-in. But this time Nicolas Cannasse’s great work on the hxformat library was my reference.

I will add two optimizations specific for PBJ files. TAAS will not be used here since it is only an unnecessary overhead. You do not have to crack a nut with a sledgehammer. The PBJ format is already register based and has certain useful invariants.

To cleanup some mistakes of the PixelBender compiler I will add:

  • Copy propagation
  • Dead Code Elimination

The compiler is not bad. Compared to the ASC it is a beauty of technology that makes use of the LLVM. However I think there must be some mistake in the code since unnecessary registers are used (Note: I doubt this is LLVMs fault but more the way how methods like sampleNearest are bound by Adobe). This can be solved with the simple optimizations I will add.

I will add some more things as well like a GLSL conversion or a DSL to write PixelBender kernels in Scala. If we get lucky this will also lead to a true cross platform opensource compiler for the PixelBender language. I think I will name that compiler Hydra :P

So I Recorded A New Video

This time recorded on Ubuntu. Did I mention 64bit already?
Do not miss my session at FOTB for a live demo.

Putting Things In Perspective

I am back home in Germany from my trip to San Francisco where I initially announced JITB at FITC. I did not expect it to get around that quickly and that a quick-and-dirty video filmed with my phone would get so much coverage.

I want to put a lot of things regarding JITB in perspective here as a followup to the various comments that I received via mail, reddit, etc.

Flash Replacement

JITB is not a Flash replacement. Imagine a F1 race car and a family van. The family van comes with air conditioning, a radio and a lot of comfort. For the F1 car you will probably have to wear a helmet and need an engineering team to get it running.
The important factor for me is that JITB will run very fast under certain conditions. A race car is also not a jeep. JITB will not support all features of the Flash Player. If you search for a Flash replacement you might want to take a look at lightspark.

Performance

Java is slow and the world is flat. That being said I will not talk about Java performance. JITB compiles to native Java code with a certain overhead. An ActionScript 3 closure is converted into an anonymous class for instance.
JITB converts ActionScript 3 bytecode to Java bytecode at runtime and performs various optimizations. This way we can leverage the speed of the JVM for ActionScript and get great results.
That being said there is also a problem of course. Startup time is not very good. JITB and its parent project Apparat are implemented in the Scala programming language and written for multi core architectures. The startup costs are high and JITB is only useful for long living applications. However compiling ActionScript to Java can be done AOT. This means you need to deal only with the normal JVM startup time. The Flash Player API is implemented in pure Java.

The compiler used for JITB is doing relatively naive optimizations at the moment. Namely constant folding, copy propagation, dead code elimination and strength reduction. An older proof of concept version I implemented a year ago featured also loop invariant code motion, inline expansion and tail-recursive optimizations. The new compiler framework is very powerful and I will add even more algorithms and a graph coloring register allocator for example. So there is some more NP-complete fun ahead making startup time even worse.

Purpose

We need a Flash Player that performs very fast for special purposes. We could use JITB at Audiotool to render mixdowns of tracks or other companies could use it to run their ActionScript code on the server side. You can use JITB to create an offline application that runs on a client machine. You can hack JITB to do what you want. Someone could potentially write a web framework for ActionScript and you could execute that code on Google App Engine if compiled AOT. And it is definitly possible to create Android applications using ActionScript. JITB’s terrain is everything but the browser in my opinion. However I can imagine that someone would be interested in creating a plugin version. With some clever simple caching algorithms it could make sense to get around startup costs but I am not interested in doing this.

Legal

There are no legal obligations to face since both the AVM2 and SWF specifications are published by Adobe. It is also not illegal to compile code for the JVM.

ActionScript Subset

By “a subset of the language” I really mean the language and not the API. JITB supports currently only statically typed ActionScript code. However the internal language model can be adjusted to support dynamic typing as well and with Java 7 things got even easier. In fact JITB does support dynamic code as long as it is able to infer types correct. Does this mean that I am willing to implement the full Flash Player API all by myself? Hell no.

In the next weeks I will probably create a better example that is easier to understand and get some other stuff ready so that you can try everything for yourself.

Introducing JITB

My talk at FITC San Francisco is over and I want to share some of the anouncements from today with you. At the end of my talk I was showing JITB.

What you see in the YouTube video I posted a while ago is a Java program executing a SWF. For FITC I added some more code and an OpenGL based Display List renderer. In other words: I wrote a Flash Player.

However I should rephrase that statement and say I am attempting to build a Flash Player. The current state is available in the sf2010-sprint clone of Apparat. I will merge the changes into the main Apparat branch when I am back home in Germany.

JITB is currently able to translate a subset of ActionScript code at runtime into Java bytecode and runs nearly at the same speed as native Java. This is a really huge improvement compared to standard ActionScript performance. A lot of smart people worked on the JVM and made it really fast. Apparat will allow you to leverage all this hard work in the future. I am also shooting for Java interoperability at some level so that you can call Java classes from within ActionScript. Hopefully you will be able to use JITB on your desktop machine, on a server or on an Android phone. Basically everywhere Java runs.

There are still a lot of things missing. The whole Flash API needs to be implemented. And the Display List rendering needs a proper OpenGL implementation. However I thought this might be some cool stuff to share with you in its early stages.
My hope is that more people start contributing to the project. Maybe some OpenGL guru wants to take care of the Display List rendering or someone else likes to help implement the Flash API in Java.

I also showed a Raytracer by Nico Zimmermann during my presentation and promised to put the URL on my blog so here it is. His company is called Britzpetermann and the address is http://www.britzpetermann.com/.

Update: Please do not think that this implementation is 30x faster than the Flash Player developed by Adobe. One(!) microbenchmark is never a number you should count on. I would like to make clear that I never said this.

Apparat RC6: Say Hello To An Old Friend

Patrick Le Clec’h is an active committer to the Apparat project and recently we just merged his work into the main branch. With a couple of other changes this is now a good time for another release candidate. Patrick added a good old friend to Apparat: The __asm function. You might remember __asm from my work on the now deprecated AS3C project.

However the Apparat version is much better. First of all we have put a lot of work into Apparat to make such transformations rock-solid. AS3C had its issues and was never a reliable tool. But there are a lot of new great features Patrick implemented. You can mix AS3 in your bytecode as well. __as3 is the best friend of __asm. Because sometimes writing pure bytecode is very verbose and not necessary.

A simple trace('Hello World!') with pure bytecode would look like this. Please note the FindPropStrict and CallPropVoid operations which reference trace.

__asm(
  FindPropStrict(AbcQName('trace', AbcNamespace(NamespaceKind.PACKAGE, ''))),
  PushString('Hello World!'),
  CallPropVoid(AbcQName('trace', AbcNamespace(NamespaceKind.PACKAGE, '')), 1)
);

Finding the object in the correct namespace is often a very cumbersome task. Thanks to __as3 we can also write this in a much more conciese way.

__asm(
  FindPropStrict(__as3(trace)),
  PushString('Hello World!'),
  CallPropVoid(__as3(trace), 1)
);

Note that the ASM compiler will try to guess the required name once it is requested by an operation. You can use __as3 also for other tasks.

var x: int = 1;
__asm(
  FindPropStrict(__as3(trace)),
  __as3(x < 10),
  CallPropVoid(__as3(trace), 1)
);

This would trace "true" for instance. If you are curious about the ASM syntax I can recommend you using the dump tool. It produces code which is nearly __asm-ready. We will probably write another output so you can directly transform existing code to __asm calls.

If you are interested in some more examples the Apparat Math replacements make use of __asm now as well. IntMath is a good example for an inlined class where you are using maybe a simple method like IntMath.abs and the heavy lifting is done behind the scenes using inline assembler. To use the ASM expansion you have to process your SWF file with TDSI. It is by default turned on.

LZMA compression in Apparat RC5

Matryoshka avec moustache

I have released Apparat RC5 at GoogleCode. It contains a really cool feature which is called LZMA compression.

Reducer has advanced a lot during the last couple of weeks. It is now also a strong SWF compression tool even if you do not have any PNG files it can compress. You may ask: “What is that Matryoshka doing there? And why the hell the top hat?” The top hat: I do not know. The Matryoshka: I can explain.

The Flash Player does not understand LZMA. SWF files are compressed using good old DEFLATE. So what happens? Apparat extracts your original SWF. It compresses it again using the LZMA algorithm. The compressed SWF is injected into another SWF that contains an LZMA decoder. Size, background color, frame rate, etc. get adjusted. Finally you get a new SWF that contains your old SWF and a decoder to extract it at runtime. The overhead of the decoder is currently at around 5kb and I hope I can get it even smaller.

When you open that SWF with the Flash Player it will extract your original file and load it. Another nice feature is that I created different versions of the runtime decoder. One is using a classic preloader which is great if your SWF is a little bit bigger. And hey: it is a preloader for free so you do not have to deal with the [Frame] hassle. But here is the catch. We at audiotool.com always write our SWF files in the same style and I can just hope you do the same or use the great InitInjector by Valentin Simonov.

Your main SWF class or the so called DocumentClass must make sure that a stage is available before accessing it. This is really easy:

public function Main() {
  addEventListener(Event.ADDED_TO_STAGE, init)
  if(null != stage) init()
}

private function init(event: Event = null): void {
  removeEventListener(Event.ADDED_TO_STAGE, init)
  // your original constructor code goes here ...
}

Stick to that rule or InitInjector can automate it for you. Otherwise you will get a runtime exception that the stage is null. So this is one new feature. The other one is actually pretty standard. If you compile and link against a SWC file all classes will come in their own ABC file. Each ABC file has a constant pool. So if you link against 1000 classes you get 1000 constant pools. Reducer can merge all those files into a single one with some minor exceptions. It can also sort the constant pool so that constants which are used frequently consume less bytes when accessed. The funk-as3 test runner which links against FlexUnit and the Flex framework is only loosing 3.01% of its weight with the old Reducer. The new version reduces it by 17.81% already thanks to the ABC merging. Combine that with some LZMA love and we get 35.34%.

Besides you can call the LZMA compression as often as you want for some basic obfuscation. The LZMA compression alone is already a (weak) obfuscation of your bytecode.

Last but not least: Good news everyone! Scala 2.8 arrived so this is the last time you will have to update it for a while.

You can download the latest Apparat version at GoogleCode. Scala 2.8.0 is required.