Using_C _Libraries_in_Flash_Player_and_AIR Jim_Corbett

Document Sample
Using_C _Libraries_in_Flash_Player_and_AIR Jim_Corbett Powered By Docstoc
					®






   
    



    

    

    




        ®



    

    


    


    









        ®

                                     Open Source Code Density by Language

    
                                700
        
                                600

                               500




            Lines of Code (M)
                                400
    
                                300

                                200
    
                                100
    
                                 0
    

    




                                                                             ®

                                                     Scimark 2 Composite Score



                       10000


                                                                                                1020
                      1000                                                          580
                                                              317          383
                                               304
       MFlops (log)
                        100

                                   12

                        10




                          1
                               AS3 on AIR   FlaCC C      C# VS 2008      CLR C     JRE 6     C VS 2008
                                                                                  Update 5




                                                                                                         ®

    

    

    




        ®

    

    

    

    

        




            ®

    

               
    

                   
    

           
    

           




                        ®

    




    

        

    

    

    




            ®

    /* all values are ref counted */
    void AS3_Acquire(AS3_Val obj);
    void AS3_Release(AS3_Val obj);
    /* obj[prop] */
    AS3_Val AS3_GetS(AS3_Val obj, const char *prop);
    /* obj[prop] = val */
    AS3_Val AS3_SetS(AS3_Val obj, const char *prop, AS3_Val val);
    /* AS3 value creation */
    AS3_Val AS3_StringN(const char *str, int len);
    AS3_Val AS3_Int(int n);
    AS3_Val AS3_Number(double n);
    /* AS3 value conversion */
    typedef char *AS3_Malloced_Str;
    AS3_Malloced_Str AS3_StringValue(AS3_Val obj);
    int AS3_IntValue(AS3_Val obj);
    double AS3_NumberValue(AS3_Val obj);
    /* func.apply(thiz, params:Array) */
    AS3_Val AS3_Call(AS3_Val func, AS3_Val thiz, AS3_Val params);




                                                                    ®

    typedef AS3_Val (*AS3_ThunkProc)(void *data, AS3_Val params);

    /* function(...params):* { return proc(data, params); } */
    AS3_Val AS3_Function(void *data, AS3_ThunkProc proc);

    /* create a C function pointer that thunks to thiz.func(...)
      int (*myfunc)(const char *s, double n) =
        AS3_Shim(someFunc, someThiz, "IntType”, “StrType, DoubleType", false);
      the function pointer is PERMANENT! */
    void *AS3_Shim(AS3_Val func, AS3_Val thiz, const char *rt, const char *tt, int varargs);




    /* create a Proxy object that delegates callProperty, etc. to the
       delegate Object returned in *delObj... in the flash_delegate namespace!
       i.e., delgates to flash_delegate::callProperty, not public callProperty
    */
    AS3_Val AS3_Proxy(AS3_Val *delObj);




                                                                                               ®





    ®
                                                  // implement library main entry point
    // include glue API                            int main() {
    #include "AS3.h“
                                                       // create AS3 Function for catThunk
                                                       AS3_Val catVal = AS3_Function(NULL,
    // implement string “cat” call for AS3
    AS3_Val catThunk(void *data, AS3_Val args){                catThunk);

        AS3_Val result = AS3_Undefined();              // create library object with
        char *s1 = NULL, *s2 = NULL;                   // property “cat” holding Function
        // pull out first argument as a string         AS3_Val result = AS3_Object(
        AS3_ArrayValue(args, "StrType, StrType",               “cat: AS3ValType", catVal);
          &s1, &s2);
                                                       // lib object now owns stemVal
        if(s1 && s2) {                                 // so release reference
          // get the length of both strings            AS3_Release(catVal);
          int len = strlen(s1) + strlen(s2);
         // alloc some memory for them                 // hand the lib object back to AS3 land!
         char *catted = (char *)malloc(len + 1);       AS3_LibInit(result);
         // copy in the strings                        // XXX never get here!
         strcpy(catted, s1);                           return 0;
         strcat(catted, s2);                       }
         // convert to AS3 string
         result = AS3_String(catted);
         // and free the memory
         free(catted);
        }
        return result;
    }

                                                                                                  ®






    


        class CLibInit
        {
           public function init():*;
        }


    




                                       ®



    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
              <![CDATA[
                    import cmodule.example.CLibInit;

                   private var libInit:CLibInit = new CLibInit();
                   private var lib:* = libInit.init();

                   private function go():void
                   {
                             str.text = lib.cat(str.text,
                                       “ rules!”);
                   }
              ]]>
    </mx:Script>
    <mx:TextInput id=“str" x="10" y="10"/>
    <mx:Button x="10" y="40" label=“Go!" click=“go()"/>
    </mx:Application>




                                                                                   ®

              


// inject C code with top-level curlies
{
// include defs for hyperbolic trig functions
#include <math.h>
}
// expose hyperbolic trig
public function sinh(x:Number):Number;
public function cosh(x:Number):Number;
public function tanh(x:Number):Number;




                                                ®
package alchemy.math {
   public class HTrig {
            import cmodule.htrig.CLibInit;
            protected static const _lib_init:cmodule.htrig.CLibInit =
                 new cmodule.htrig.CLibInit();
            protected static const _lib:* = _lib_init.init();
            static public function sinh(x:Number):Number {
                 return _lib.sinh(x);
            }
            static public function cosh(x:Number):Number {
                 return _lib.cosh(x);
            }
            static public function tanh(x:Number):Number {
                 return _lib.tanh(x);
            }
   }
}

                                                                        ®



    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
           layout="absolute">
    <mx:Script>
           <![CDATA[
               import alchemy.math.HTrig;
           ]]>
    </mx:Script>
    <mx:TextInput id=“inp" x="10" y="10"/>
    <mx:Button x="10" y="40" label=“Sinh!“
           click=“inp.text = String(HTrig.sinh(Number(inp.text)))"/>
    </mx:Application>




                                                                       ®

    

{
// include def for frexp:
#include <math.h>
/*
double frexp ( double x, int * exp );
Get significand and exponent
x = significand * 2 ^ exponent
*/
}

// expose frexp
public function frexp(x:Number):Array
{
        // C implementation!
        int exponent;
        double significand = frexp(x, &exponent);
        return AS3_Array(“DoubleType, IntType",
                significand, exponent);
}




                                                    ®

    

    

    




        ®


    // return the ByteArray holding C memory
    public function get ram():ByteArray;
    // allocate C memory to hold an image
    public function alloc(bytes:uint):uint;
    // free C memory
    public function free(ptr:uint):void;
    // encode an image
    public function encode(complete:Function, dstPng:BytArray, progress:Function,
     imagePtr:uint, width:uint, height:uint):void;




                                                                                    ®

    




    




        ®





    ®

    

    

    

    

    

    

    


    




        ®

    

        

        

        

    

        

    

        




            ®







    ®





    








        ®
     __asm(lbl("___vfprintf_state0"))                                                  __asm(push(i1!=0), iftrue,
     __asm(lbl("___vfprintf__XprivateX__BB79_0_F"))                         target("___vfprintf__XprivateX__BB79_4_F"))
           mstate.esp -= 4; __asm(push(mstate.ebp), push(mstate.esp),            __asm(lbl("___vfprintf__XprivateX__BB79_3_F"))
op(0x3c), stack(-2))                                                                   i1 = (1)
           mstate.ebp = mstate.esp                                                     __asm(push(i1), push(_ret_2E_993_2E_0_2E_b), op(0x3a), stack(-
           mstate.esp -= 2640                                               2))
           i0 = (0)                                                                    __asm(push(i1), push(_ret_2E_993_2E_2_2E_b), op(0x3a), stack(-
           i1 = ((__xasm<int>(push((mstate.ebp+16)), op(0x37))))            2))
           __asm(push(i1), push((mstate.ebp+-84)), op(0x3c), stack(-2))                __asm(push(i1), push(___nlocale_changed_2E_b), op(0x3a),
           __asm(push(i0), push((mstate.ebp+-86)), op(0x3a), stack(-2))     stack(-2))
           i0 = ((__xasm<int>(push((mstate.ebp+8)), op(0x37))))                  __asm(lbl("___vfprintf__XprivateX__BB79_4_F"))
           i1 = ((__xasm<int>(push((mstate.ebp+12)), op(0x37))))                       i1 = (__2E_str1881)
           __asm(push(i1), push((mstate.ebp+-2295)), op(0x3c), stack(-2))              i3 = ((__xasm<int>(push(_ret_2E_993_2E_0_2E_b), op(0x35))))
           i1 = ((__xasm<int>(push(___mlocale_changed_2E_b), op(0x35))))               i4 = ((__xasm<int>(push((i0+12)), op(0x36))))
           i2 = ((mstate.ebp+-1504))                                                   i1 = ((i3!=0) ? i1 : 0)
           i3 = ((mstate.ebp+-1808))                                                   __asm(push(i1), push((mstate.ebp+-2124)), op(0x3c), stack(-2))
           __asm(push(i3), push((mstate.ebp+-2259)), op(0x3c), stack(-2))              i1 = (i0 + 12)
           i3 = ((mstate.ebp+-1664))                                                   __asm(push(i1), push((mstate.ebp+-2025)), op(0x3c), stack(-2))
           __asm(push(i3), push((mstate.ebp+-2097)), op(0x3c), stack(-2))              i1 = (i4 & 8)
           i3 = ((mstate.ebp+-304))                                                    __asm(push(i1==0), iftrue,
           __asm(push(i3), push((mstate.ebp+-2115)), op(0x3c), stack(-2))   target("___vfprintf__XprivateX__BB79_7_F"))
           i3 = ((mstate.ebp+-104))                                              __asm(lbl("___vfprintf__XprivateX__BB79_5_F"))
           __asm(push(i3), push((mstate.ebp+-2277)), op(0x3c), stack(-2))              i1 = ((__xasm<int>(push((i0+16)), op(0x37))))
           __asm(push(i1!=0), iftrue,                                                  __asm(push(i1!=0), iftrue,
target("___vfprintf__XprivateX__BB79_2_F"))                                 target("___vfprintf__XprivateX__BB79_9_F"))
     __asm(lbl("___vfprintf__XprivateX__BB79_1_F"))                              __asm(lbl("___vfprintf__XprivateX__BB79_6_F"))
           i1 = (1)                                                                    i1 = (i4 & 512)
           __asm(push(i1), push(___mlocale_changed_2E_b), op(0x3a),                    __asm(push(i1!=0), iftrue,
stack(-2))                                                                  target("___vfprintf__XprivateX__BB79_9_F"))
     __asm(lbl("___vfprintf__XprivateX__BB79_2_F"))                              __asm(lbl("___vfprintf__XprivateX__BB79_7_F"))
           i1 = ((__xasm<int>(push(___nlocale_changed_2E_b), op(0x35))))               mstate.esp -= 4




                                                                                                                                                        ®

      


    // create a C parser and return the pointer
     public function ParserCreate(encoding:String):uint;
     // free a C parser
     public function ParserFree(parser:uint):void;
     // set user data on a parser
     public function SetUserData(parser:uint, data:*):void;




                                                              ®
                              


    public class Parser            /* XML_Parser data structure (artist’s
    {                              rendition) */
      // pointer to the C          typedef struct
                                   {
      // XML_Parser
                                     /* data set by SetUserData */
      private var _ptr:uint;         AS3_Val userData;
    }                                /* ... */
                                   } *XML_Parser;




                                                                            ®

/* Trusty Flash-style weak reference
*/
final class WeakReference {
    // dictionary with weak keys
    private var _dict:Dictionary = new Dictionary(true);

    public function WeakReference(obj:Object) {
             // use "obj" as a key w/ arbitrary value...
             // since keys are weak, the key/val pair will
             // disappear when the object is no longer
             // reachable
             _dict[obj] = 1;
    }

    public function get obj():Object {
             // if there's a key, it'll be our obj!
             for(var key:* in _dict)
                  return key;
             // otherwise, it's been collected
             return null;
    }
}


                                                             ®

/* Track when objects "owned" by another object
   have their owners collected
*/
final class ReferenceTracker {
  // weak-keyed dictionary mapping owner => [owned,...]
  private var _reachable:Dictionary = new Dictionary(true);
  // set of live "owned" objects
  private var _live:Array = [];

    // record that "owner" has a reference to "obj"
    public function addRef(owner:Object, obj:*):void;

    // record that "owner" lost a reference to "obj"
    // and we are not to report it dead
    public function removeRef(owner:Object, obj:*):void;

    // return an array of objects that have "died" since last sweep
    public function sweep():Array;



                                                                      ®

public class Parser {
  // ReferenceTracker to clean up unreachable C parsers
  private static var _parserRefTracker:ReferenceTracker;
  // single instance of the C library
  private static var _lib:*;

    // lazily initialize the C library
    private static function initLib():void {
       if(!_lib) {
         // …
         // set up the reference tracker
         _parserRefTracker = new ReferenceTracker();
         // …
       }
    }
    // sweep for unreachable C parsers
    public static function sweep():void {
      if(_lib)
         _parserRefTracker.sweep().forEach(_lib.ParserFree);
    }
}

                                                               ®

public class Parser {
  public function Parser(encoding:String = “”) {
    // maybe init the C lib
    initLib();


        // sweep for dead Parsers
        sweep();

        // create the C parser
        _ptr = _lib.ParserCreate(encoding);


        // weakly link ourselves to the parser --
        // a strong reference here would lead to the
        // corresponding C structures keeping us from
        // getting garbage collected!
        _lib.SetUserData(_ptr, new WeakReference(this));


        // start tracking it for GC
        _parserRefTracker.addRef(this, _ptr);
    }
}




                                                           ®

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:18
posted:11/10/2011
language:English
pages:34