<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.joa-ebert.com - Blog of Joa Ebert &#187; Flash</title>
	<atom:link href="http://blog.joa-ebert.com/category/flash/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.joa-ebert.com</link>
	<description>Actionscript3, Flash, Scala, Java, C#, C++, Algorithms &#38; Imageprocessing</description>
	<lastBuildDate>Fri, 11 Nov 2011 11:13:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Software Transactional Memory and Audiotool</title>
		<link>http://blog.joa-ebert.com/2011/02/25/stm-and-audiotool/</link>
		<comments>http://blog.joa-ebert.com/2011/02/25/stm-and-audiotool/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 22:18:17 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[knowledge]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[audiotool]]></category>
		<category><![CDATA[stm]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=755</guid>
		<description><![CDATA[I have tweeted a while ago about the fact that Audiotool does heavily rely on a so called software transactional memory. In this blog post I want to discuss the implementation of our STM and why it is useful. Wikipedia defines STM as: In computer science, software transactional memory (STM) is a concurrency control mechanism [...]]]></description>
			<content:encoded><![CDATA[<p>I have tweeted a while ago about the fact that <a href="http://www.audiotool.com/" target="_blank" title="Audiotool">Audiotool</a> does heavily rely on a so called <a href="http://en.wikipedia.org/wiki/Software_transactional_memory" title="STM">software transactional memory</a>. In this blog post I want to discuss the implementation of our STM and why it is useful.</p>
<p>Wikipedia defines STM as:</p>
<blockquote><p>In computer science, software transactional memory (STM) is a concurrency control mechanism analogous to database transactions for controlling access to shared memory in concurrent computing.</p></blockquote>
<p>First of all when reading this you might think that an STM is not necessary since ActionScript does not support true concurrency and also the <a href="http://bugs.adobe.com/jira/browse/ASL-23" target="_blank">shared-nothing worker proposal</a> will not allow you concurrent memory access. While this holds true you may not forget that concurrency becomes an issue when you have just access to a single core but on multiple machines.</p>
<p>A lesser known fact about Audiotool is also that we have a built-in system for real time collaboration since its beginning. Due to conceptional issues and other prioritized features we were never able to roll it out as a full feature but the technology base is there.</p>
<p>When it comes to multiplayer gaming and network latency you will always have to figure out a system which allows you to share a certain state across multiple machines. In some games the state is synchronized across a certain server. An example is an FPS like Quake3. The Audiotool is unlike Quake3 not a FPS and different conditions have to be met. And this is the reason why I have choosen to implement an STM with very optimistic concurrency control.</p>
<p>The basic idea of my system is to use atomic transactions with commit and revert operations. Those are handled by a transaction manager which performs the basic tasks of an STM. That means: execute all transactions until an error occurs, roll back and try again. Each transaction in the Audiotool contains a guard. The guard defines whether or not one should still execute the transaction.</p>
<p><img src="/wp-content/images/stm_flow.gif" width="193" height="344" border="0" style="float: left; margin-right: 8px;"/>Here is an example of why a guard is important and how all this stuff works. You have two Audiotool instances running that share the same state. We call them <em>A</em> and <em>B</em>. <em>A</em> and <em>B</em> are connected via P2P no an arbitrary network. This means exchanging messages introduces latency and we cannot guarantee that <em>A</em> is at the same state of <em>B</em>.</p>
<p>So what happens? t<sub>0</sub> is committed by <em>A</em>, serialized and sent to <em>B</em> who is committing the same transaction. The same applies to t<sub>1</sub>. t<sub>2</sub> is initiated by <em>B</em>, serialized and sent to <em>A</em>. Everything works fine until <em>B</em> commits t<sub>4</sub>. While t<sub>4</sub> is being transferred to <em>A</em>, <em>A</em> created t<sub>5</sub> and committed it. This means <em>A</em> never saw t<sub>4</sub> when it committed t<sub>5</sub> and <em>B</em> would continue with t<sub>6</sub> ignoring t<sub>5</sub>. <em>A</em> will actually receive t<sub>4</sub> after he commited t<sub>5</sub> so the system will revert t<sub>5</sub>, commit t<sub>4</sub>, commit t<sub>5</sub> if the guard does not prevent it, and both continue at t<sub>6</sub>.</p>
<p>To explain the guard: Imagine the t<sub>5</sub> transaction includes modifications on a device in the Audiotool that is deleted by t<sub>4</sub>. In that case t<sub>5</sub> will never be executed.</p>
<p>So what does this imply? You can guess that each modification of the Audiotool state is in fact handled by a transaction and we carefully have to pick the guards. E.g. if an editor is referenced by a transaction it is part of the guard. However this introduces a second issue: references. Sharing references of objects across a network is a tricky task. I am using &#8220;boxes&#8221; to solve this issue. A box can hold a value and it is guaranteed that it will hold the same value at the same state across the network. A box can be serialized and will be shared between commit and revert states. This means if t<sub>n</sub> creates an object which is referenced by t<sub>n+1</sub> both will use the same box. This also means that I can safely revert t<sub>n+1</sub> and then t<sub>n</sub> and commit them without having to worry that both still reference the same object. And this even works across the network. And in fact we can now also identify whether or not one transaction would conflict with a different one which is a very important condition for the actual implementation.</p>
<p>Right now you might have figured out that a transaction in the Audiotool has the following properties:</p>
<ul>
<li>It is serializable so it can be transferred across the network.</li>
<li>All object references must be stored via &#8220;boxes&#8221;.</li>
<li>A guard is used to determine whether or not to commit a transaction.</li>
<li>Transactions can be committed and reverted.</li>
</ul>
<p>A lot of stuff one has to reason about. But although we do not support live collaboration at the moment we are using the STM. Why? The reason is quite simple. The STM gives us history for free. Since everything is serializable via a very lightweight protocol we can take the last 500 transactions for instance and store them as a compressed ByteArray in memory instead of each as a single object with all its references.</p>
<p>Another very nice option is testing. A serializable history means that one simply has to press a super secret shortcut to dump the whole history and send it to the responsible developer who can reason about every single step that happened which ultimately led to the error. In development mode I usually commit, revert and commit each transaction. Then I also serialize and deserialize them and do the whole thing again.</p>
<p>Since transactions are known by the system we can also write a fuzzer that executes lots of crazy stuff. Sort of Android&#8217;s monkey mode. And ultimately I personally hope that we will get to the point where we will enable live collaboration in the Audiotool of course.</p>
<p>The last feature I implemented is the automatic transformation of arbitrary transactions to a compound transaction. You can guess what this feature actually means for the user :). In fact it is very complex and I implemented it with the STM using only a couple lines of code (of course that is just half the story &#8230;).</p>
<p>If you are interested in writing your own multi user application I think this is a very nice approach since collisions do not happen very often from my experience and the optimistic concurrency in a P2P environment achieves great results in terms of overall latency and feeling. The <a href="http://www.waveprotocol.org/" target="_blank">Google Wave protocol</a> and their <a href="http://www.waveprotocol.org/whitepapers/operational-transform" target="_blank">operational transform</a> is also an interesting read.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2011/02/25/stm-and-audiotool/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=755&amp;md5=f361069b28000698af6f6b5a80c8c2f6" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2011/02/25/stm-and-audiotool/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=755&amp;md5=f361069b28000698af6f6b5a80c8c2f6" type="text/html" />
	</item>
		<item>
		<title>Apparat 1.0 RC7 Is Here</title>
		<link>http://blog.joa-ebert.com/2010/10/06/apparat-1-0-rc7-is-here/</link>
		<comments>http://blog.joa-ebert.com/2010/10/06/apparat-1-0-rc7-is-here/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 12:19:03 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[asmifier]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jitb]]></category>
		<category><![CDATA[lwjgl]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=681</guid>
		<description><![CDATA[I wanted to make a simple bug fix release for Apparat since I solved some bugs and issues. However there are two additional features that are worth mentioning. First of all Apparat comes now with an ASMifier tool. This allows you to let Apparat generate code from an existing SWF. It will create a file [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to make a simple bug fix release for Apparat since I solved some bugs and issues. However there are two additional features that are worth mentioning. First of all Apparat comes now with an ASMifier tool. This allows you to let Apparat generate code from an existing SWF. It will create a file that contains a basic class structure with statements that you can directly use for <code>__asm</code> optimizations. You can also suppress all log output and turn Apparat into quiet mode by specifying <code>-Dapparat.quiet=true</code>.</p>
<p>Also worth mentioning: JITB ships now by default with Apparat. What does it mean? <del datetime="2010-10-06T11:43:52+00:00">Quadruple-rainbow in your face.</del> You can now run your SWF files with JITB if you follow the five golden steps to pure happiness:</p>
<ol>
<li>Download and install <a href="http://www.scala-lang.org/downloads" target="_blank" title="Scala Download">Scala 2.8.0</a></li>
<li>Type <code>scala</code> in a terminal, then type <code>println(System getProperty "java.library.path" split java.io.File.pathSeparatorChar mkString "\n")</code> and remember one of the folders</li>
<li><a href="http://sourceforge.net/projects/java-game-lib/files/Official%20Releases/LWJGL%202.5/" target="_blank" title="LWJGL Download">Download LWJGL 2.5</a> and extract somewhere</li>
<li>Copy the native libraries which are located in <code>lwjgl-2.5/native/YOUR OS/</code> into one of the folders that the Scala command showed you</li>
<li>Open a terminal, go into the Apparat installation directory and type <code>./jitb some.swf</code> to launch JITB
</ol>
<p>Now here is the problem. JITB is not complete and so it will probably fail with your SWF &#8212; In fact I can nearly gaurantee you that it will not launch your SWF. I included JITB basically because it already allows you to use GLSL shaders very easy and I know a lot of people would like to play around with that.</p>
<p>However I have created an archive of all files I showed at FOTB besides the files that came from <a href="http://www.derschmale.com/" title="DerSchmale" target="_blank">David&#8217;s laptop</a> since I do not have them on my machine. You might be interested in checking out Example12.as which is the one that uses GLSL shaders. If you want to compile your own version you will need to link apparat-ersatz.swc as an external library since it contains the <code>ContinuousFileLoader</code> and <code>GLSLShader</code> class. Happy hacking!</p>
<ul>
<li><a href="http://code.google.com/p/apparat/downloads/detail?name=jitb_examples.zip" title="jitb_examples.zip" target="_blank">Download the JITB Examples</a></li>
<li><a href="http://apparat.googlecode.com/" target="_blank" title="Apparat">Apparat on GoogleCode</a></li>
</ul>
<p><b>Update:</b> Also read <a href="http://www.derschmale.com/2010/10/07/ray-tracing-with-pixel-bender-using-jitb/" target="_blank" title="Ray tracing with Pixel Bender using JITB">Ray tracing with Pixel Bender using JITB</a> by David Laenarts for details on the FOTB demos.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/10/06/apparat-1-0-rc7-is-here/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=681&amp;md5=695570dfdaff6985bd8902b49a5d493b" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/10/06/apparat-1-0-rc7-is-here/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=681&amp;md5=695570dfdaff6985bd8902b49a5d493b" type="text/html" />
	</item>
		<item>
		<title>Opening The Blackbox</title>
		<link>http://blog.joa-ebert.com/2010/10/03/opening-the-blackbox/</link>
		<comments>http://blog.joa-ebert.com/2010/10/03/opening-the-blackbox/#comments</comments>
		<pubDate>Sun, 03 Oct 2010 17:57:00 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[avm]]></category>
		<category><![CDATA[flashplayer]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jitb]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=674</guid>
		<description><![CDATA[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. A [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p><span id="more-674"></span></p>
<p>A part of the Flash Player is the ActionScript Virtual Machine (AVM) which is responsible for executing the code that is bundeled in your SWF file. This piece of software called <a href="http://www.mozilla.org/projects/tamarin/" target="_blank" title="Tamarin">Tamarin</a> is open source and released under the <a href="http://www.mozilla.org/projects/tamarin/faq.html#license" target="_blank" title="Tamarin License">MPL/GPL/LGPL Triple License</a>.</p>
<p>Being able to look at the heart of the Flash Player does reveal a lot to the interesting reader. However such a virtual machine is a complex piece of software and you can be lost without any guidance and will maybe not even be able to compile it unless you are familiar with such systems. <a href="http://jpauclair.net" target="_blank" title="jpauclair">Jean-Philippe Auclair&#8217;s blog</a> contains a lot of interesting Tamarin and Flash Player releated articles if you want to know more about the VM. Of course you can also read about <a href="https://developer.mozilla.org/en/MMgc" title="MMgc" target="_blank">MMgc</a> &#8212; the garbage collection &#8212; directly at the Mozilla developer network.</p>
<p>This article is titled &#8220;Opening The Blackbox&#8221;. Although Tamarin might be some kind of blackbox to most of us the source code is available. We can dig into it and understand how it works. The Flash Player however is not completely open source and we do not know about its implementation details. Unless Adobe is opening up the source code we will not know which exact algorithm is used for <a href="http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html#noise()" target="_blank" title="flash.display.BitmapData">BitmapData.noise</a> for instance.</p>
<blockquote><p>Fills an image with pixels representing random noise.</p></blockquote>
<p>This quote taken from the documentation does not tell you much about how to calculate this noise. In this situation I would create some algorithm that fills a BitmapData also with random noise. But until we know which algorithm is used to calculate that noise it will never be the exact same noise as the one of the Flash Player. For now we will have to live with it. There is no (legal) way to figure out the algorithm.<br />
Of course there are also other classes like ByteArray which have methods like <code>readByte</code> that do not need any extra explanation. But ByteArray also has some implementation specific details. How does it grow when you exceed its length for instance? Fortunately ByteArray is something <a href="http://hg.mozilla.org/tamarin-central/file/fbecf6c8a86f/axscript/ByteArrayGlue.cpp#l138" target="_blank" title="ByteArrayGlue.cpp">you can find</a> in the Tamarin source code. JITB uses a different algorithm however which you can find <a href="http://code.google.com/p/apparat/source/browse/apparat-playerglobal/src/main/java/flash/utils/ByteArray.java#161" target="_blank" title="ByteArray.java">here</a>.</p>
<p>But what else do we got? There are some funny things you will notice. Usually <code>Sprite(x)</code> is an explicit cast. This is true for any statement like this. However <a href="http://help.adobe.com/en_US/AS3LCR/Flash_10.0/package.html#Number()" target="_blank" title="Number()"><code>Number(x)</code></a> is a conversion with specific details how a value is converted. This is also true for some other expressions like <code>Boolean()</code>.</p>
<p>The <code>playerglobal.swc</code> contains all classes the Flash Player knows about. It should and it does with some minor differences. Of course it could be a bug on my end but some interfaces are missing. And they are suspicious since they cause/have special behaviour. Have a look at the <a href="http://code.google.com/p/apparat/source/browse/apparat-taas/src/main/scala/apparat/taas/frontend/abc/AbcFrontend.scala#32" target="_blank" title="AbcFrontend.scala">AbcFrontend</a> code. The <code>Synthetic</code> object contains part of the AST that is synthesized since those interfaces are missing in <code>playerglobal.swc</code>.</p>
<p>A lot of the Flash Player implementation details have made it into the <code>DisplayObject</code> and its subclasses. You cannot extend from <code>DisplayObject</code> and you cannot implement <code>IBitmapDataDrawable</code>. Even more interesting is the amount of classes that you cannot really use. <a href="http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/geom/Transform.html" target="_blank" title="flash.geom.Transform"><code>flash.geom.Transform</code></a> is such a class. How is <code>concatenatedMatrix</code> working if you would create your own instance of the <code>Transform</code> object?</p>
<p>Of course somewhere in the Flash Player will be some code that creates a <code>Transform</code> object. This will hold a reference to the original <code>DisplayObject</code> and concat the matrices up to the stage if you call <code>concatenatedMatrix</code>. The JITB implementation adds some special methods to the <code>Transform</code> class in such cases. Those methods are always prefixed with JITB$ if they are public. Another interesting fact is that you can modify the appearance of a <code>DisplayObject</code> by setting the matrix of the <code>Transform</code> object. This also has to change the scale, x, y and rotation values of the <code>DisplayObject</code>. There are a dozen of souch cases. Graphics would be an obvious candidate to talk about. I would advise you to take a look at <a href="http://wahlers.com.br/claus/blog/" target="_blank">Claus&#8217; blog</a> for <a href="http://wahlers.com.br/claus/blog/hacking-swf-1-shapes-in-flash/" target="_blank">everything you never wanted to know about shapes</a>.</p>
<p>Also something you probably never cared about is the way how <code>URLLoader</code> works. I do not care about the specific implementation details either. However one thing is important to keep in mind. Loaders have to work asynchronous since they do not block. This means your Flash content runs while waiting for an event like <code>Event.COMPLETE</code>. This is where it gets interesting since threads enter the game. This would be a simple view: ActionScript runs in one thread, the loader in a second thread. First of all we have to keep in mind that the ActionScript code runs in a loop which is basically only triggered by events like <code>Event.ENTER_FRAME</code> or user input. Only the code in your <code>DocumentClass</code> is the one that is initiated without an event. So how does this look like in pseudo-code?</p>
<pre>
while(NoErrorOccurred &#038;&#038; Running) {
  Dispatch Event.ENTER_FRAME to each DisplayObject
  Render DisplayList
  Dispatch Event.EXIT_FRAME to each DisplayObject
  Sleep(1000 / FrameRate - Elapsed)
}
</pre>
<p>Okay but how does an <code>Event.COMPLETE</code> make it into this loop when it comes from a different thread in which the loader runs? If the loader would simply dispatch this event when it completes the code would not run in the main thread. This means you could end up with ActionScript code running in parallel which would cause chaos and destruction. So what do you do? The current approach in JITB is to gather all events and dispatch them at the beginning of a frame. So basically the code looks now like this:</p>
<pre>
while(NoErrorOccurred &#038;&#038; Running) {
  Dispatch All Gathered Events
  Dispatch Event.ENTER_FRAME to each DisplayObject
  Render DisplayList
  Dispatch Event.EXIT_FRAME to each DisplayObject
  Sleep(1000 / FrameRate - Elapsed)
}
</pre>
<p>The implementation specific details can be found in <a href="http://code.google.com/p/apparat/source/browse/apparat-playerglobal/src/main/java/jitb/events/EventSystem.java" target="_blank" title="EventSystem.java">EventSystem.java</a> class. There are also some utility methods like <code>futureDispatch</code> to make development easier. Dynamic audio requires to dispatch an event that is filled with content. The thread in which the audio is passed to the sound card has to wait until <code>SampleDataEvent</code> is filled with new content. This also reveals a problem. The audio calculation has to wait for a complete ActionScript frame until new material is available. In fact such synchronization points are problematic for a task that requires very low latency. You can hear this when your ActionScript code takes very long to process the new audio and you get a stutter-noise or audible gap. Unfortunately there is nothing you can do about this problem at the moment besides keeping the cost of your ActionScript code as low as possible.</p>
<p>Of course everything is only my interpretation. The Flash Player might not suffer from the problems I describe here since someone might have come up with a better implementation. In fact I would doubt that the Flash Player works for dynamic audio the same way I do it currently.</p>
<p>The last blog post of this series will be more about how you can implement parts of the Flash Player API in Java so that JITB understands them and vice versa. Of course we can create our own <code>playerglobal.swc</code> as well and add new native classes like <a href="http://code.google.com/r/joaebert-sf2010-sprint/source/browse/apparat-playerglobal/src/main/java/jitb/display/GLSLShader.java" target="_blank" title="GLSLShader.java"><code>GLSLShader</code></a> which I demoed at FOTB. </p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/10/03/opening-the-blackbox/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=674&amp;md5=1bf8f52bd4912172087d59fed924367f" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/10/03/opening-the-blackbox/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=674&amp;md5=1bf8f52bd4912172087d59fed924367f" type="text/html" />
	</item>
		<item>
		<title>How JITB converts ActionScript to Java</title>
		<link>http://blog.joa-ebert.com/2010/10/02/how-jitb-converts-actionscript-to-java/</link>
		<comments>http://blog.joa-ebert.com/2010/10/02/how-jitb-converts-actionscript-to-java/#comments</comments>
		<pubDate>Sat, 02 Oct 2010 16:45:23 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[avm]]></category>
		<category><![CDATA[bytecode]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jitb]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[taas]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=670</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>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.</p>
<p><span id="more-670"></span></p>
<h3>JITB and TAAS</h3>
<p>JITB makes use of TAAS. A three address code intermediate language. TAAS has its own set of rules and typesystem that I defined for myself. Method overloading is supported for instance. And there is no concept of array access. Code like <code>x = a[0]</code> is converted to <code>x = a.getIndex(0)</code>. In TAAS terms the name of a method is also not worth a penny since it is always using a reference based lookup.</p>
<p>What I love about TAAS is that it has a really small instruction set. Array access is just a method call like any other method call. No extra instructions added. This makes optimizations really slick and easy to develop. Since the code is statically typed you also always know which method is being called and you could construct a call graph and do whole program optimizations which is a huge bonus. Escape analysis is something that is now finally possible for me.</p>
<p>JITB uses a frontend that parses ActionScript bytecode and creates an AST which is then transformed and passed to a backend that creates Java bytecode. The class and package structure is stored in a tree form. Method bodies are always stored in a graph representation. The interesting problem is to convert ActionScript into TAAS since it is no direct mapping and some statements are not supported in the same way you get them form the ActionScript bytecode. Then the next interesting problem is to convert this code into Java bytecode which is also not a direct mapping.</p>
<p>An example for such a problem are implicit getters and setters. TAAS does not have a concept of getters and setters but understands methods. So whenever the ActionScript bytecode has a <code>GetProperty</code> instruction I try to figure out if this is a field or not. If it is a field I generate a <code>TLoad</code> instruction, if it is an implicit getter it will be converted to a <code>TCall</code> instruction. However if it cannot be determined since the class might be dynamic a <code>TCall</code> instruction will be generated which uses the special <code>TGetProperty</code> method and this will be resolved at runtime.<br />
When converting to Java a <code>TLoad</code> can be easily translated to a <code>GETFIELD</code> operation. When it is a <code>TCall</code> I first lookup whether or not it is a special native function. If it is a special function like <code>TGetProperty</code> I insert Java code like <code>object.JITB$getProperty(name)</code>. If it is a normal function I simply insert an invoke operation.</p>
<h3>Closures for Java</h3>
<p>Java 1.6 does not support closures. This means Java does not understand the concept of a reference to a function. Code like <code>addEventListener(Event.ENTER_FRAME, onEnterFrame)</code> is not possible with Java since <code>onEnterFrame</code> is a reference to the <code>onEnterFrame</code> function which is defined somewhere else in your code.</p>
<p>I took the idea from Scala and how they support closures in the JVM. Basically when code like <code>addEventListener(Event.ENTER_FRAME, onEnterFrame)</code> occurrs it will be translated to the TAAS instruction <code>TCall(TReg(0), TaasMethod(addEventListener, ...), List(TString("enterFrame"), TClosure(TaasMethod(onEnterFrame, ...))), None)</code>. This basically means that the method <code>addEventListener</code> is called on the object in register zero with two arguments of which one a closure and it has no result which is indicated by <code>None</code>.</p>
<p>This instruction is expanded to the following Java code. Please remember that it is always Java bytecode. I think it is just easier to understand if I write the corresponding Java code here.</p>
<pre>
this.addEventListener("enterFrame", new Function1<Event, Object>() {
  override Object call(Event arg) { callVoid(arg); return null; }
  override void callVoid(Event arg) { onEnterFrame(arg); }
});
</pre>
<p>Function1 represents a function of arity one. The AVM can call any method as either void or with an expected result. If the method has a result and you call it via <code>CallPropVoid</code> the resulting object is ignored. If however you have a method that does not have a result and you call it via <code>CallProperty</code> the <code>null</code> object will be pushed on the stack.</p>
<p>The Java code in EventDispatcher which would call closures basically now only looks like this:</p>
<pre>
void dispatchEvent(Event event) {
  for(Function1<Event, Object> listener : listenersFor(event.type))
    listener.call(event)
}
</pre>
<h3>Dynamic code in Java</h3>
<p>Since I want to target Java 1.6 I do not make use of the Java 1.7 opcodes like <code>invokedynamic</code>. Because TAAS is already statically typed we have only in very rare cases the need to make a dynamic lookup. This is done by some helper classes or methods. Every ActionScript based class extends from <code>jitb.lang.Object</code>. The <code>jitb.lang</code> package represents the ActionScript&#8217;s toplevel. The <code>Object</code> class has certain helper methods like <code>JITB$getProperty</code> and <code>JITB$setProperty</code>. Those methods throw an error by default if an object is not dynamic but they can implement the behaviour to store values in a HashMap for dynamic classes.<br />
However currently dynamic method lookup is not supported. Code like <code>a['method'+Math.random()]()</code> fails since it is impossible to know upfront which method is called. But this can be supported as well. It is just very cumbersome and annoying.</p>
<h3>Emulating the AVM in the JVM</h3>
<p>What kind of error do you expect for this kind of code: <code>var x: String = null; trace(x.toString());</code>? This creates a TypeError in ActionScript but a NullPointerException in Java. Same for things like <code>var x: A = new A(); var y: B = B(x);</code> which would result in a Java ClassCastException if A is not assignable to B.<br />
JITB offers an option which is by default turned on the get the exact same exceptions like the AVM would throw them. This means that a Java cast is converted to a call like <code>AVM.cast(x, B.class)</code> with the option turned on or the simple Java <code>CHECKCAST</code> bytecode when the option is turned off. Basically expecting something to be null in a try-catch block is very silly in my honest opinion. So to get rid of this overhead you can disable this extra step of correctness.</p>
<p>Another interesting issue is the fact thatthe AVM can throw any object. Java however expects that a throwable object extends from the Throwable class. Of course the basic <code>jitb.lang.Object</code> class could simply extend Throwable. However I do not want that overhead and at any time. Also I do not want to break how classes extend each other. If you do something like <code>throw "string"</code> it is converted to <code>throw new Throw<String>("string")</code>. Throw does extend Throwable and whenever it is catched the value is simply extracted.</p>
<h3>To box or not to box?</h3>
<p>ActionScript allows you do use int as an object with a lot of special behaviours. Same happens for values like Boolean or Number. <code>var x: int; trace(x);</code> outputs 0 but not null. But it is also possible to call <code>0.toString()</code> which indicates that the integer value <code>0</code> is treated like an object that has methods like <code>toString()</code>.<br />
In Java however you have a real <code>int</code> primitive and the <code>Integer</code> object. <code>0.toString()</code> does not compile but you would rather do <code>Integer.toString(0)</code>.</p>
<p>Of course Java is much faster when using primitive data types when appropriate. JITB does this since it handles primitive types like real primtives for Java. This means a method like <code>function add(x: int, y: int): int { return x + y}</code> is converted to <code>int add(int x, int y) { return x + y }</code>. However when you have a method that expects an Object type a primitive will be boxed into a compatible type.</p>
<p>Last but not least what happens for code like <code>0.toString()</code> or other methods? A possibility would be to emit code like <code>new jitb.lang.Number(0).toString()</code> but that does not make sense in most of the cases. Instead those calls are treated specially with a call like <code>jitb.lang.Number.JITB$toString(0)</code> and we get rid of an extra allocation.</p>
<h3>Conclusion</h3>
<p>I hope you understand a little bit better now how JITB works internally and what the main gotchas are in such an implementaiton. The journey is not over since I have to add support for anonymous methods and although I talked about things like <code>throw</code> I still have to add support for try-catch. Also a lot of other basic features are still missing but I doubt that they would cause any problems.</p>
<p>The other side of the story is the Flash Player API inside of JITB which is maybe worth a blog post like this as well since it reveals a lot of other funny and interesting gotchas.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/10/02/how-jitb-converts-actionscript-to-java/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=670&amp;md5=d839aa2d65bc21169a914c85dee2bda9" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/10/02/how-jitb-converts-actionscript-to-java/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=670&amp;md5=d839aa2d65bc21169a914c85dee2bda9" type="text/html" />
	</item>
		<item>
		<title>JITB&#8217;s PixelBender support</title>
		<link>http://blog.joa-ebert.com/2010/10/01/jitbs-pixelbender-support/</link>
		<comments>http://blog.joa-ebert.com/2010/10/01/jitbs-pixelbender-support/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 15:35:37 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[hydra]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[glsl]]></category>
		<category><![CDATA[jitb]]></category>
		<category><![CDATA[pixelbender]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=664</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>I have demoed support for PixelBender shaders in JITB at the <a href="http://www.flashonthebeach.com/" target="_blank">FOTB 2010</a> 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 <a href="http://www.derschmale.com/" target="_blank">David Lenaerts</a>. 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.<br />
<span id="more-664"></span></p>
<h3>Step #1: Parsing PixelBender data</h3>
<p>PixelBender compiles down to PBJ which is a two-address based bytecode format. Basically it contains instructions like this one which I have taken from <a href="http://www.ncannasse.fr/projects/pbj" target="_blank">Nicolas&#8217; blog</a>:</p>
<pre>  sampleNearest f2, text0[f0.rg]
  sampleNearest f3, text1[f0.rg]
  mov f4, f2
  mul f4, f3
  mov f1, f4</pre>
<p>Those PBJ files are parsed by Apparat into high level structures. This happens basically the same way I do it for ActionScript bytecode. Thanks to the work of Nicolas Cannasse this was a walk in the park.</p>
<h3>Step #2: Optimizing PixelBender bytecode</h3>
<p>The PixelBender compiler does not produce optimal code as noted by Nicolas. You can see it in the code I just posted. Or you can simply compile and empty shader and take a look at the disassembled output. Apparat performs only two very simple optimizations for PixelBender which are written especially for PBJ. Thos include copy propagation and dead code elimination. The compiler does create code which is not bad thanks to <a href="http://www.llvm.org/" target="_blank">LLVM</a> but there are unnecessary copies going on which are removed by Apparat.</p>
<h3>Step #3: Loop detection</h3>
<p>PixelBender <b>still</b> has no loops since its initial introduction in October 1st in 2007. Tomorrow it is October 1st in 2010. Go figure. So since there are no loops the only way people write loops in PixelBender is basically by copy and paste or using preprocessor directives. With JITB I want to send real shaders to the graphics card and I do want to make use of loops. So I wrote a PBJ bytecode based copy and paste detector which is based on ideas of the <a href="http://pmd.sourceforge.net/" target="_blank">PMD</a> copy and paste detector. When a segment is detected in a sequence I convert it to a loop. That way I can reduce the amount of data I have to send to the graphics card. This is very important since in the case of the demos I showed at FOTB they contained around 50.000 instructions. And my cheap graphics card was complaining that there are too many instrucitons. With the loop conversion this number drastically decreased.</p>
<h3>Step #4: Converting PixelBender bytecode to GLSL</h3>
<p>It is very easy to convert PixelBender to GLSL. The two address code format can be translated with some minor tweaks to GLSL with a very simple mapping. However this is not really optimal since you have only a two address code. When exporting to GLSL I perform one additional step which expands the two address based code to a three address based code. That way I do not emit a lot of unnecessary copies again.</p>
<p>That is basically the recipie to convert PixelBender PBJ files to GLSL shaders that perform well on current graphics card hardware. There are additional steps involved to get OpenGL shaders to work like PixelBender in Flash but they are only minor tweaks. I have no comparable metrics right now. However I will create a JITB applet version so you can have a look for yourself soon.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/10/01/jitbs-pixelbender-support/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=664&amp;md5=0cf6eb4a85dfbfd59053adc3948edf8e" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/10/01/jitbs-pixelbender-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=664&amp;md5=0cf6eb4a85dfbfd59053adc3948edf8e" type="text/html" />
	</item>
		<item>
		<title>Disappointment No. 3</title>
		<link>http://blog.joa-ebert.com/2010/10/01/disappointment-no-3/</link>
		<comments>http://blog.joa-ebert.com/2010/10/01/disappointment-no-3/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 14:43:35 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[as3doc]]></category>
		<category><![CDATA[as3v]]></category>
		<category><![CDATA[code coverage]]></category>
		<category><![CDATA[flexmojos]]></category>
		<category><![CDATA[jitb]]></category>
		<category><![CDATA[opensource]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=661</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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 <a href="http://www.audiotool.com/" target="_blank">audiotool.com</a> it is hard for me to find some time off to develop those applications. Some of them are even not written for myself &#8212; like the FlexMojos code coverage.</p>
<p>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.</p>
<p>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. </p>
<p>I am just sad that there is no dialog at all. This happened three times now. I will not continue doing this.</p>
<p>That does not mean I will stop working on Apparat and JITB. Only no more enterprise releated open source software.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/10/01/disappointment-no-3/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=661&amp;md5=2381f8d77fe482e64e9391afe6ba84da" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/10/01/disappointment-no-3/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=661&amp;md5=2381f8d77fe482e64e9391afe6ba84da" type="text/html" />
	</item>
		<item>
		<title>PixelBender Support In Apparat</title>
		<link>http://blog.joa-ebert.com/2010/09/07/pixelbender-support-in-apparat/</link>
		<comments>http://blog.joa-ebert.com/2010/09/07/pixelbender-support-in-apparat/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 08:35:38 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[hydra]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[pixelbender]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=651</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Since PixelBender is becomming a more popular technology in the Flash ecosystem I decided to add first-class Apparat support for it.</p>
<p>As you <a href="http://blog.joa-ebert.com/2008/09/08/pixelbender-runtime-compilation/" title="PixelBender Runtime Compilation" target="_self">might know</a> I have done a couple of <a href="http://blog.joa-ebert.com/2008/10/08/pixelbender-outline-view/" title="PixelBender Outline View" target="_self">different</a> <a href="http://blog.joa-ebert.com/pbdt/" target="_self" title="PBDT">tools</a> for PixelBender already.</p>
<p>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.</p>
<p>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 <a href="http://ncannasse.fr/" target="_blank" title="Nicolas Cannasse">Nicolas Cannasse&#8217;s</a> great work on the <a href="http://hxformat.googlecode.com/" title="hxformat" target="_blank">hxformat</a> library was my reference. </p>
<p>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.</p>
<p>To cleanup some mistakes of the PixelBender compiler I will add:</p>
<ul>
<li>Copy propagation</li>
<li>Dead Code Elimination</li>
</ul>
<p>The compiler is not bad. Compared to the ASC it is a beauty of technology that makes use of the <a href="http://www.llvm.org/" target="_blank" title="LLVM">LLVM</a>. 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.</p>
<p>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 <i>Hydra</i> :P</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/09/07/pixelbender-support-in-apparat/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=651&amp;md5=7c242af7c1b61870a087c1fe598f0cec" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/09/07/pixelbender-support-in-apparat/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=651&amp;md5=7c242af7c1b61870a087c1fe598f0cec" type="text/html" />
	</item>
		<item>
		<title>So I Recorded A New Video</title>
		<link>http://blog.joa-ebert.com/2010/08/31/so-i-recorded-a-new-video/</link>
		<comments>http://blog.joa-ebert.com/2010/08/31/so-i-recorded-a-new-video/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 12:38:49 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jitb]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[taas]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=647</guid>
		<description><![CDATA[This time recorded on Ubuntu. Did I mention 64bit already? Do not miss my session at FOTB for a live demo.]]></description>
			<content:encoded><![CDATA[<div align="center"><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/atzHF7YGp6Y?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/atzHF7YGp6Y?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></div>
<p>This time recorded on Ubuntu. Did I mention 64bit already?<br />
Do not miss my session at <a href="http://www.flashonthebeach.com/" target="_blank">FOTB</a> for a live demo.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/08/31/so-i-recorded-a-new-video/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=647&amp;md5=66836cca038fcf8883ba718d7edfd8de" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/08/31/so-i-recorded-a-new-video/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=647&amp;md5=66836cca038fcf8883ba718d7edfd8de" type="text/html" />
	</item>
		<item>
		<title>Putting Things In Perspective</title>
		<link>http://blog.joa-ebert.com/2010/08/30/putting-things-in-perspective/</link>
		<comments>http://blog.joa-ebert.com/2010/08/30/putting-things-in-perspective/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 16:34:18 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[avm]]></category>
		<category><![CDATA[jitb]]></category>
		<category><![CDATA[jvm]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=642</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>I am back home in Germany from my trip to San Francisco where I initially announced JITB at <a href="http://www.fitc.ca/" target="_blank" title="FITC">FITC</a>. 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.</p>
<p>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.</p>
<h3>Flash Replacement</h3>
<p>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.<br />
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  <a href="http://sourceforge.net/apps/trac/lightspark" target="_blank">lightspark</a>.</p>
<h3>Performance</h3>
<p>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.<br />
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.<br />
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 <a href="http://www.scala-lang.org/" target="_blank">Scala</a> 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 <a href="http://en.wikipedia.org/wiki/AOT_compiler" target="_blank" title="AOT compiler on Wikipedia">AOT</a>. This means you need to deal only with the normal JVM startup time. The Flash Player API is implemented in pure Java.</p>
<p>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.</p>
<h3>Purpose</h3>
<p>We need a Flash Player that performs very fast for special purposes. We could use JITB at <a href="http://www.audiotool.com/" target="_blank" title="Audiotool">Audiotool</a> 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&#8217;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 <del datetime="2010-08-30T16:00:23+00:00">clever</del> simple caching algorithms it could make sense to get around startup costs but I am not interested in doing this. </p>
<h3>Legal</h3>
<p>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.</p>
<h3>ActionScript Subset</h3>
<p>By &#8220;a subset of the language&#8221; 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.</p>
<p>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.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/08/30/putting-things-in-perspective/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=642&amp;md5=a7fc274af0332ec97d12c0a14f5f1cda" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/08/30/putting-things-in-perspective/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=642&amp;md5=a7fc274af0332ec97d12c0a14f5f1cda" type="text/html" />
	</item>
		<item>
		<title>Introducing JITB</title>
		<link>http://blog.joa-ebert.com/2010/08/19/introducing-jitb/</link>
		<comments>http://blog.joa-ebert.com/2010/08/19/introducing-jitb/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 02:07:41 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[experiments]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[fitc]]></category>
		<category><![CDATA[flashplayer]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jitb]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[san francisco]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=636</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<div align="center"><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/EMm893PRDJM?fs=1&amp;hl=de_DE"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/EMm893PRDJM?fs=1&amp;hl=de_DE" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></div>
<p>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 <a href="http://www.youtube.com/watch?v=-IXvf17GWVI" target="_blank" title="JITB">JITB</a>.</p>
<p>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.</p>
<p>However I should rephrase that statement and say I am attempting to build a Flash Player. The current state is available in the <a href="http://code.google.com/r/joaebert-sf2010-sprint/source/list" target="_blank" title="sf2010-sprint clone">sf2010-sprint</a> clone of Apparat. I will merge the changes into the main Apparat branch when I am back home in Germany.</p>
<p>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.</p>
<p>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.<br />
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.</p>
<p>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 <a href="http://www.britzpetermann.com/" target="_blank" title="Britzpetermann">http://www.britzpetermann.com/</a>.</p>
<p><b>Update:</b> 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.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/08/19/introducing-jitb/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=636&amp;md5=e3cd48304d4dfb8fee13de1b216671c2" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/08/19/introducing-jitb/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=636&amp;md5=e3cd48304d4dfb8fee13de1b216671c2" type="text/html" />
	</item>
		<item>
		<title>Apparat And Maven</title>
		<link>http://blog.joa-ebert.com/2010/07/03/apparat-and-maven/</link>
		<comments>http://blog.joa-ebert.com/2010/07/03/apparat-and-maven/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 09:10:06 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[flexmojos]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=610</guid>
		<description><![CDATA[Two days ago I made a major change to the Apparat repository. I completely restructured the layout and fully integrated Apparat with Maven. We have now a plugin and archetypes for easy tooling. I also synchronized Apparat with the Maven central repository two weeks ago. You might ask what the hell this is about. So [...]]]></description>
			<content:encoded><![CDATA[<p>Two days ago I made a major change to the Apparat repository. I completely restructured the layout and fully integrated Apparat with Maven. We have now a plugin and archetypes for easy tooling. I also synchronized Apparat with the Maven central repository two weeks ago.</p>
<p>You might ask what the hell this is about. So in the current state you can download Apparat from Google Code. Then you have to have a working Scala installation which has been used to build Apparat. Whenever Scala is updated, I have to updated Apparat, and you will have to download Apparat again and install a new Scala version. This is absolutely cumbersome. This will change of course when Scala 2.8 is officially released.</p>
<p>I know that some people will always require command line access for Apparat. I am sorry for you at the moment that we have to play this game until 2.8 is out.</p>
<p>For the rest this is good news. If you have a working Maven 3.x version you can use the Apparat plugin and get automatic updates. This means you have to configure your project only once and do not bother with Scala and Apparat anymore. In fact if you want to you could also use the Apparat snapshot repository and get live updates.</p>
<p>Project configuration and setup is something one should not have to deal with. Therefore you can use the archetypes. I have built one for TurboDieselSportInjection.</p>
<pre><code>mvn archetype:generate \
  -DarchetypeRepository=http://oss.sonatype.org/content/repositories/snapshots \
  -DarchetypeGroupId=com.googlecode.apparat \
  -DarchetypeArtifactId=apparat-archetype-tdsi \
  -DarchetypeVersion=1.0-SNAPSHOT</code></pre>
<p>This terminal command is all you need to do to create a new project that is ready to compile &#8212; with TurboDieselSportInjection enabled. And it will automatically use the latest Apparat version.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/07/03/apparat-and-maven/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=610&amp;md5=bcb51c0080d2d9b512aee8ae6293b0a6" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/07/03/apparat-and-maven/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=610&amp;md5=bcb51c0080d2d9b512aee8ae6293b0a6" type="text/html" />
	</item>
		<item>
		<title>New Apparat Example</title>
		<link>http://blog.joa-ebert.com/2010/05/26/new-apparat-example/</link>
		<comments>http://blog.joa-ebert.com/2010/05/26/new-apparat-example/#comments</comments>
		<pubDate>Wed, 26 May 2010 11:50:54 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[experiments]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[inline]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=595</guid>
		<description><![CDATA[Good news everyone. The Apparat inline expansion works now to full extent after fixing some minor bugs. A complete example is also available. Just change the paths in the build.properties file and compile everything using Ant. Use the inline feature with care. Apparat does not try to optimize your code and performs nothing but dead [...]]]></description>
			<content:encoded><![CDATA[<p>Good news everyone. The Apparat inline expansion works now to full extent after fixing some minor bugs. A complete example is also available. Just change the paths in the <code>build.properties</code> file and compile everything using Ant.</p>
<div align="center"><img src="http://blog.joa-ebert.com/wp-content/images/apparat-shot.png" width="399" height="183" alt="Apparat Example"/></div>
<p>Use the inline feature with care. Apparat does not try to optimize your code and performs nothing but dead simple inlining. This can lead to <b>slower</b> code due to the creation of lots of local registers. Your code gets also much bigger and will require more space in memory. I am actually not a fan of manual inlining at all. I think it makes only sense to inline code if you have a powerful optimizer available that will cleanup the whole mess.</p>
<p>The fun story about this example is that the inlined version is slower using the lastes Flash Player release candidate if you have only 40.000 particles. That is why I increased the number of particles to 80.000 ;). I developed the example using an old standalone player and the inlined version was nearly twice as fast. However when I watched the example in the browser with the latest release candidate the game was completely different. Kudos to Adobe for significantly improving the Flash Player performance!</p>
<ul>
<li><a href="http://www.joa-ebert.com/swfs/apparat-example/as3" target="_blank" title="Pure AS3 version">AS3-only Version</a></li>
<li><a href="http://www.joa-ebert.com/swfs/apparat-example/apparat" target="_blank" title="Inline version">Inline Version</a></li>
<li><a href="http://code.google.com/p/apparat/downloads/detail?name=apparat-ant-example.zip" target="_blank" title="Source">Source</a></li>
</ul>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/05/26/new-apparat-example/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=595&amp;md5=2ce2a0467b1d8ded7f90f209404288e1" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/05/26/new-apparat-example/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=595&amp;md5=2ce2a0467b1d8ded7f90f209404288e1" type="text/html" />
	</item>
		<item>
		<title>Inline Expansion</title>
		<link>http://blog.joa-ebert.com/2010/05/24/inline-expansion/</link>
		<comments>http://blog.joa-ebert.com/2010/05/24/inline-expansion/#comments</comments>
		<pubDate>Mon, 24 May 2010 18:12:57 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[inline expansion]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=593</guid>
		<description><![CDATA[In addition to macro expansion Apparat has now inline expansion as well. It works nearly the same way as macro expansion but without most of its limitations. To define a class for inline usage it must extend apparat.inline.Inlined and all its methods must be static. However the cool thing is that you can also return [...]]]></description>
			<content:encoded><![CDATA[<p>In addition to macro expansion Apparat has now inline expansion as well. It works nearly the same way as macro expansion but without most of its limitations. To define a class for inline usage it must extend <code>apparat.inline.Inlined</code> and all its methods must be static. However the cool thing is that you can also return values in contrast to macro expansion. You can also pass normal parameters. For instance <code>FastMath.sin(FastMath.sqrt(2.0))</code> is valid code using inline expansion. It is enabled by default in TDSI.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/05/24/inline-expansion/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=593&amp;md5=2a3742ff77e6fc190a8c9a18f200c574" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/05/24/inline-expansion/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=593&amp;md5=2a3742ff77e6fc190a8c9a18f200c574" type="text/html" />
	</item>
		<item>
		<title>Apparat For Scala 2.8 RC2</title>
		<link>http://blog.joa-ebert.com/2010/05/24/apparat-for-scala-2-8-rc2/</link>
		<comments>http://blog.joa-ebert.com/2010/05/24/apparat-for-scala-2-8-rc2/#comments</comments>
		<pubDate>Mon, 24 May 2010 13:44:37 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[7z]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[scala 2.8-rc2]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=591</guid>
		<description><![CDATA[Apparat is now available using the Scala 2.8-RC2 build. You can find appropriate downloads now on Google Code by searching for the Scala version of your choice. 7z compression on OS X should work now as well.]]></description>
			<content:encoded><![CDATA[<p>Apparat is now available using the Scala 2.8-RC2 build. You can <a href="http://code.google.com/p/apparat/downloads/list?q=label:scala-2.8.0.RC2" target="_blank" title="Apparat on Google Code">find appropriate downloads</a> now on Google Code by searching for the Scala version of your choice. 7z compression on OS X should work now as well.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/05/24/apparat-for-scala-2-8-rc2/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=591&amp;md5=256384b9411d0e3dcfc39cc0f88ee8a7" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/05/24/apparat-for-scala-2-8-rc2/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=591&amp;md5=256384b9411d0e3dcfc39cc0f88ee8a7" type="text/html" />
	</item>
		<item>
		<title>Macro Expansion</title>
		<link>http://blog.joa-ebert.com/2010/05/10/macro-expansion/</link>
		<comments>http://blog.joa-ebert.com/2010/05/10/macro-expansion/#comments</comments>
		<pubDate>Mon, 10 May 2010 17:31:34 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[apparat]]></category>
		<category><![CDATA[inline]]></category>
		<category><![CDATA[macro expansion]]></category>
		<category><![CDATA[taas]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=588</guid>
		<description><![CDATA[Apparat has another new feature called Macro Expansion. I talked about this with Nico Zimmermann at FFK in Cologne. Nico was using TDSI for a project but he was not very satisfied with it because you have to inline all inverse-square root tricks manually. This is why Apparat has now macro expansion. I am actually [...]]]></description>
			<content:encoded><![CDATA[<p>Apparat has another new feature called <a href="http://code.google.com/p/apparat/wiki/MacroExpansion" title="Macro Expansion" target="_blank">Macro Expansion</a>. I talked about this with Nico Zimmermann at FFK in Cologne. Nico was using TDSI for a project but he was not very satisfied with it because you have to inline all inverse-square root tricks manually.<br />
This is why Apparat has now macro expansion. I am actually not a big fan of it. I think a good compiler would do this for you without you having to go through all the steps. Unfortunately writing this compiler will take longer than the couple of hours I have spent on the macro expansion today.</p>
<p>So if you want to have quick and dirty inlining capabilities: <a href="http://code.google.com/p/apparat/wiki/MacroExpansion" target="_blank" title="Macro Expansion">this is for you</a>. It is an easy fix for a feature a lot of people have asked for. I will continue working on TAAS to implement this much better in the future.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/05/10/macro-expansion/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=588&amp;md5=62a1e80324e54d1a998b75f91d4a410e" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/05/10/macro-expansion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=588&amp;md5=62a1e80324e54d1a998b75f91d4a410e" type="text/html" />
	</item>
		<item>
		<title>Apparat: Crunching SWF Files Since 2009</title>
		<link>http://blog.joa-ebert.com/2010/05/07/apparat-crunching-swf-files-since-2009/</link>
		<comments>http://blog.joa-ebert.com/2010/05/07/apparat-crunching-swf-files-since-2009/#comments</comments>
		<pubDate>Fri, 07 May 2010 15:37:04 +0000</pubDate>
		<dc:creator>joa</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://blog.joa-ebert.com/?p=578</guid>
		<description><![CDATA[Apparat has a great new feature that allows you to create even smaller files. Basic SWF files are compressed using Java&#8217;s standard java.util.zip.Deflater class. This is perfectly fine. And I would even go with no compression at all during development. However when deploying you can spend some extra time compressing your SWF files with the [...]]]></description>
			<content:encoded><![CDATA[<p>Apparat has a great new feature that allows you to create even smaller files. Basic SWF files are compressed using Java&#8217;s standard <code>java.util.zip.Deflater</code> class. This is perfectly fine. And I would even go with no compression at all during development.</p>
<p>However when deploying you can spend some extra time compressing your SWF files with the best tools available. <a href="http://www.7-zip.org/" target="_blank" title="7-Zip">7-Zip</a> is for instance such a tool and achieves a great compression ratio.</p>
<p>If you have the 7z executable on your <code>PATH</code> Apparat will make use of it to achieve the best compression for your SWF files. More configuration options are available <a href="http://code.google.com/p/apparat/wiki/HiddenGems" target="_blank" title="HiddenGems">here</a>.</p>
<p>This feature is currently only implemented for SWF files and not SWCs. However every tool will make use of it by default. So if you are running Reducer and have no graphics in your SWF files you can still get a better compression.</p>
<p>An example is straight from the sources:</p>
<blockquote><p><code>
<pre>reducer -i as3\Apparat.Tests.AS3\bin\Test07.swf
[i] Apparat -- http://apparat.googlecode.com/
[i] Launching tool: Reducer
[i] Waiting for 7z ...
[i] Compression ratio: <b>18.224573%</b>
[i] Total bytes: 310
[i] Completed in 547ms.</pre>
<p></code></p></blockquote>
<p>Note please that this SWF file does not contain any graphical assets and we got still a ratio of 18%. Our main <code>audiotool.swf</code> file is compressed by about 10% &#8212; about 200kb &#8212; and contains no graphical assets either.</p>
<p>You can download the latest Apparat on <a href="http://code.google.com/p/apparat/downloads/detail?name=apparat.zip"  target="_blank" title="Download Apparat">Google Code</a>. Please note that you will need <a href="http://www.scala-lang.org/downloads" target="_blank" title="Scala Downloads">Scala 2.8 RC1</a> as well.</p>
<div class="none"><div class="g-plusone" data-href="http://blog.joa-ebert.com/2010/05/07/apparat-crunching-swf-files-since-2009/" size="standard" count="true"></div></div> <p><a href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=578&amp;md5=dd76bdf7e993bb56510fdf0bf84efe6b" title="Flattr" target="_blank"><img src="http://blog.joa-ebert.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.joa-ebert.com/2010/05/07/apparat-crunching-swf-files-since-2009/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		<atom:link rel="payment" href="http://blog.joa-ebert.com/?flattrss_redirect&amp;id=578&amp;md5=dd76bdf7e993bb56510fdf0bf84efe6b" type="text/html" />
	</item>
	</channel>
</rss>

