Every function call in the default compiler results in these two lines of code:
0 getlocal0 1 pushscope these are missing in Falcon compiled code. Another change I found was that in Falcon compiled code the Metadata is kept at class level while the default compiler moves the metadata to the property. Ist this of any significance? I could immagine that if I have a class extending a falcon compiled class then all properties in this extension would be bindable too, if extending a default compiler compiled class I would only expect the properties of the base class bindable. But that's just wild guessing ... reading ABC code is something I'm not really familiar with. When compiling this: package { [Bindable] public interface TestInterface { function someFunct():void; } } And this implementation class: package { [Bindable] public class TestClass implements TestInterface { public var tst:String; public function TestClass() { } public function someFunct():void { } } } The default compiler outputs this: public class TestClass extends Object TestInterface,flash.events::IEventDispatcher { // method_id=2309 public function TestClass():* { // derivedName null // method_info 2309 // max_stack 4 // max_regs 1 // scope_depth 4 // max_scope 5 // code_length 23 bb0 succs=[] 0 getlocal0 1 pushscope 2 getlocal0 3 findpropstrict flash.events::EventDispatcher 4 findpropstrict flash.events::IEventDispatcher 5 getlocal0 6 callproperty 7 constructprop 8 initproperty _bindingEventDispatcher 9 getlocal0 10 constructsuper 0 11 returnvoid } private var _115157tst:String public function someFunct():void { // derivedName null // method_info 2310 // max_stack 1 // max_regs 1 // scope_depth 4 // max_scope 5 // code_length 3 bb0 succs=[] 0 getlocal0 1 pushscope 2 returnvoid } [Bindable(event="propertyChange")] // metadata_id=org.apache.flex.abc.semantics.Metadata@c628c6b6 public function get tst():String { // derivedName null // method_info 2311 // max_stack 1 // max_regs 1 // scope_depth 4 // max_scope 5 // code_length 7 bb0 succs=[] 0 getlocal0 1 pushscope 2 getlocal0 3 getproperty _115157tst 4 returnvalue } public function set tst(String):void { // derivedName null // method_info 2312 // max_stack 6 // max_regs 3 // scope_depth 4 // max_scope 5 // code_length 50 bb0 succs=[bb1,bb3] 0 getlocal0 1 pushscope 2 getlocal0 3 getproperty _115157tst 4 coerce Object 5 setlocal2 6 getlocal2 7 getlocal1 8 ifstricteq bb3 bb1 succs=[bb2,bb3] 9 getlocal0 10 getlocal1 11 setproperty _115157tst 12 getlocal0 13 pushstring "propertyChange" 14 callproperty 15 iffalse bb3 bb2 succs=[bb3] 16 getlocal0 17 getlex mx.events::PropertyChangeEvent 18 getlocal0 19 pushstring "tst" 20 getlocal2 21 getlocal1 22 callproperty 23 callpropvoid bb3 succs=[] 24 returnvoid } private var _bindingEventDispatcher:flash.events::EventDispatcher public function addEventListener(String,Function,Boolean,int,Boolean):void { // derivedName null // method_info 2313 // max_stack 6 // max_regs 6 // scope_depth 4 // max_scope 5 // code_length 18 bb0 succs=[] 0 getlocal0 1 pushscope 2 getlocal0 3 getproperty _bindingEventDispatcher 4 getlocal1 5 getlocal2 6 getlocal3 7 getlocal 4 8 getlocal 5 9 callpropvoid 10 returnvoid } public function dispatchEvent(flash.events::Event):Boolean { // derivedName null // method_info 2314 // max_stack 2 // max_regs 2 // scope_depth 4 // max_scope 5 // code_length 12 bb0 succs=[] 0 getlocal0 1 pushscope 2 getlocal0 3 getproperty _bindingEventDispatcher 4 getlocal1 5 callproperty 6 returnvalue } public function hasEventListener(String):Boolean { // derivedName null // method_info 2315 // max_stack 2 // max_regs 2 // scope_depth 4 // max_scope 5 // code_length 12 bb0 succs=[] 0 getlocal0 1 pushscope 2 getlocal0 3 getproperty _bindingEventDispatcher 4 getlocal1 5 callproperty 6 returnvalue } public function removeEventListener(String,Function,Boolean):void { // derivedName null // method_info 2316 // max_stack 4 // max_regs 4 // scope_depth 4 // max_scope 5 // code_length 14 bb0 succs=[] 0 getlocal0 1 pushscope 2 getlocal0 3 getproperty _bindingEventDispatcher 4 getlocal1 5 getlocal2 6 getlocal3 7 callpropvoid 8 returnvoid } public function willTrigger(String):Boolean { // derivedName null // method_info 2317 // max_stack 2 // max_regs 2 // scope_depth 4 // max_scope 5 // code_length 12 bb0 succs=[] 0 getlocal0 1 pushscope 2 getlocal0 3 getproperty _bindingEventDispatcher 4 getlocal1 5 callproperty 6 returnvalue } public static function TestClass$():* { // derivedName null // method_info 2308 // max_stack 1 // max_regs 1 // scope_depth 3 // max_scope 4 // code_length 3 bb0 succs=[] 0 getlocal0 1 pushscope 2 returnvoid } } And Falcon generates this: [Bindable(event="propertyChange")] // metadata_id=org.apache.flex.abc.semantics.Metadata@c628c6b6 public class TestClass extends Object TestInterface,flash.events::IEventDispatcher { // method_id=2738 public function TestClass():* { // derivedName TestClass // method_info 2738 // max_stack 3 // max_regs 1 // scope_depth 0 // max_scope 1 // code_length 16 bb0 succs=[] 0 getlocal0 1 pushscope 2 getlocal0 3 findpropstrict flash.events::EventDispatcher 4 getlocal0 5 constructprop 6 setproperty _bindingEventDispatcher 7 getlocal0 8 constructsuper 0 9 returnvoid } private var tst:String public function get tst():String { // derivedName tst // method_info 2730 // max_stack 1 // max_regs 1 // scope_depth 0 // max_scope 0 // code_length 5 bb0 succs=[] 0 getlocal0 1 getproperty tst 2 returnvalue } public function set tst(String):void { // derivedName tst // method_info 2731 // max_stack 6 // max_regs 3 // scope_depth 0 // max_scope 0 // code_length 47 bb0 succs=[bb1,bb3] 0 getlocal0 1 getproperty tst 2 setlocal2 3 getlocal2 4 getlocal1 5 ifstricteq bb3 bb1 succs=[bb2,bb3] 6 getlocal0 7 getlocal1 8 setproperty tst 9 getlocal0 10 pushstring "propertyChange" 11 callproperty 12 iffalse bb3 bb2 succs=[bb3] 13 getlocal0 14 getlex mx.events::PropertyChangeEvent 15 getlocal0 16 pushstring "tst" 17 getlocal2 18 getlocal1 19 callproperty 20 callpropvoid bb3 succs=[] 21 returnvoid } public function someFunct():void { // derivedName someFunct // method_info 2732 // max_stack 1 // max_regs 1 // scope_depth 0 // max_scope 1 // code_length 1 bb0 succs=[] 0 returnvoid } private var _bindingEventDispatcher:flash.events::EventDispatcher public function addEventListener(String,Function,Boolean,int,Boolean):void { // derivedName addEventListener // method_info 2733 // max_stack 6 // max_regs 6 // scope_depth 0 // max_scope 0 // code_length 16 bb0 succs=[] 0 getlocal0 1 getproperty _bindingEventDispatcher 2 getlocal1 3 getlocal2 4 getlocal3 5 getlocal 4 6 getlocal 5 7 callpropvoid 8 returnvoid } public function dispatchEvent(flash.events::Event):Boolean { // derivedName dispatchEvent // method_info 2734 // max_stack 2 // max_regs 2 // scope_depth 0 // max_scope 0 // code_length 10 bb0 succs=[] 0 getlocal0 1 getproperty _bindingEventDispatcher 2 getlocal1 3 callproperty 4 returnvalue } public function hasEventListener(String):Boolean { // derivedName hasEventListener // method_info 2735 // max_stack 2 // max_regs 2 // scope_depth 0 // max_scope 0 // code_length 10 bb0 succs=[] 0 getlocal0 1 getproperty _bindingEventDispatcher 2 getlocal1 3 callproperty 4 returnvalue } public function removeEventListener(String,Function,Boolean):void { // derivedName removeEventListener // method_info 2736 // max_stack 4 // max_regs 4 // scope_depth 0 // max_scope 0 // code_length 12 bb0 succs=[] 0 getlocal0 1 getproperty _bindingEventDispatcher 2 getlocal1 3 getlocal2 4 getlocal3 5 callpropvoid 6 returnvoid } public function willTrigger(String):Boolean { // derivedName willTrigger // method_info 2737 // max_stack 2 // max_regs 2 // scope_depth 0 // max_scope 0 // code_length 10 bb0 succs=[] 0 getlocal0 1 getproperty _bindingEventDispatcher 2 getlocal1 3 callproperty 4 returnvalue } public static function TestClass$():* { // derivedName null // method_info 2739 // max_stack 0 // max_regs 1 // scope_depth 0 // max_scope 0 // code_length 1 bb0 succs=[] 0 returnvoid } } Really need to create a tool for this ... :) Chris ________________________________________ Von: Christofer Dutz <christofer.d...@c-ware.de> Gesendet: Sonntag, 2. November 2014 11:46 An: dev@flex.apache.org Betreff: AW: AW: AW: [FALCON] Bindable interfaces? Last night I found out that I could simply let the falcon SWFdump dump the swf of the default compiler any I actually got results I could compare. One thing that sprung my eyes immediately was that with the old compiler the first two commands of every method I could find were identical and were completely missing from the falcon code. But ignoring the first two statements (even a one-line return null function had these). The results were semantically allmost identical. Only the setter of a Bindable variable were slightly differntly implemented and the private variable didn't have the number prefix ... don't know if this could be a problem: private var tst:String; public function set tst(val:String):void { ... } pubic function get tst():String { ... } Could this cause problems? Chris -----Ursprüngliche Nachricht----- Von: Alex Harui [mailto:aha...@adobe.com] Gesendet: Samstag, 1. November 2014 19:41 An: dev@flex.apache.org Betreff: Re: AW: AW: [FALCON] Bindable interfaces? I think you can set -compiler.compress=false and get Falcon to produce a SWF that the old swfdump can dump. On 11/1/14, 10:55 AM, "Christofer Dutz" <christofer.d...@c-ware.de> wrote: >Well I sent the output of the default compiler through the default >swfdump -abc with the falcon built swf of the same project using >falcon-swfdump -abc ... unfortunateley I can't really compare the two >directly. The falcon version is far more readable than the default one >but is more than twice the size. From a brief look it does seem as if >the generated code is as it should (even after commenting out the >problematic code). > >Would really need to have a tool that automatically compiles a project >with both and creates the swfdump of the results in a compareable way >as my current manual way is rather anoying. > >Chris > >________________________________________ >Von: Alex Harui <aha...@adobe.com> >Gesendet: Samstag, 1. November 2014 15:14 >An: dev@flex.apache.org >Betreff: Re: AW: [FALCON] Bindable interfaces? > >On 11/1/14, 6:25 AM, "Christofer Dutz" <christofer.d...@c-ware.de> wrote: > >>Ok ... digging through the handling of Bindable metadata it seems that >>the code that was causing problems was redundant. The logic in >>ASCompilationUnit that changed the parent class of classes extending >>Object seems obsolete because even if commenting out the entire code >>in ASCompilationUnit binding stil seems to work. >> >>So I guess we should remove this particular piece of code from >>ASCompilationUnit. Probably this would also get rid of the problems I >>was having. > >I would recommend find out where else the change to extend >IEventDispatcher happens, and then maybe Gordon/Darrell would have a >better opinion on how it should work. > >> >>Well I tried to compare the generated outputs, but couldn't manage to >>keep the generated output. >>While looking for the reason for this, in >>flex-falcon/compiler/src/org/apache/flex/compiler/config/Configuration >>.ja >>v >>a >> >>I could see that the configuration of >>compiler.keep-generated-actionscript is marked as not supported and >>isn't implemented at all. I don't quite know how I should compare the output. > >It is true that Falcon does not keep-generated-actionscript. It >generates ABC directly from the AST. That allows the opportunity to >output ABC patterns that don’t have true or readable AS equivalents >someday. I don’t think that is done now, but think about tail-call >optimizations and things like that. > >Maybe I wasn’t clear, but I’m trying to say that MXMLC is the gold >standard. You want to compare MXMLC’s output with and without >[Bindable] and then teach Falcon to do the same. >Keep-generated-actionscript should work there for a lot of it, but I >would also use SWFDump -abc to see things that aren’t apparent in the >generated AS. > >-Alex >