I was wrong, there is a way


#1

The little details is here

Let me give more context :slight_smile:.

In the AS3 ecosystem, many tech or way of doing are close to each other but not necessarily compatible,
when it come to compile C/C++ sources to work inside an AVM2 runtime, the way Redtamarin is doing it is different than the way CrossBridge is doing it is different than the way ActionScript Native Extensions are doing it.

And in the case of crossbridge being incompatible with redtamarin, I was wrong.

There is a way to rewrite or patch or update the crossbridge POSIX layer so it can work with redtamarin.

Here a little example in C_Run.as

  /**
  * @private
  */
  public const domainClass:Class = (function():Class
  {
    // try to get player ApplicationDomain class
    try
    {
      var flashsystemNS:Namespace = new Namespace("flash.system");

      return flashsystemNS::["ApplicationDomain"];
    }
    catch(e:*) { }

    // try to get shell Domain class
    var avmplusNS:Namespace = new Namespace("avmplus");

    return avmplusNS::["Domain"];
  })();

In the different AVM2 runtimes

  • Flash / Adobe AIR
    flash.system.ApplicationDomain
  • avmshell (avmplus shell)
    avmplus.Domain
  • redshell (Redtamarin shell)
    shell.Domain

so patching C_Run in the ssimplest way for redtamarin would be something like that

  /**
  * @private
  */
  public const domainClass:Class = (function():Class
  {
    // try to get shell Domain class
    var redtamarinNS:Namespace = new Namespace("shell");

    return redtamarinNS::["Domain"];
  })();

a bit more complicated would be

  /**
  * @private
  */
  public const domainClass:Class = (function():Class
  {
    // try to get player ApplicationDomain class
    try
    {
      var flashsystemNS:Namespace = new Namespace("flash.system");

      return flashsystemNS::["ApplicationDomain"];
    }
    catch(e:*) { }

    // try to get avmplus shell Domain class
    try
    {
      var avmplusNS:Namespace = new Namespace("avmplus");

      return avmplusNS::["Domain"];
    }
    catch(e:*) { }

    // try to get redtamarin shell Domain class
    try
    {
      var redtamarinNS:Namespace = new Namespace("shell");

      return redtamarinNS::["Domain"];
    }
    catch(e:*) { }

    return null;
  })();

Simply put, you know a particular runtime provide a certain API and so you detect which APi you returns related to which runtime your code run within.

It is very similar to The case when you donโ€™t want Node.js where you provvide an implementation of the ChakraHost API, so even if the runtime is different your API layer is compatbile.

To the point that I already planed to provide different โ€œglueโ€ libraries so dev can compile JS libraries made for ChakraHost, Node.js, etc. and run them within the AVM2 of Redtamarin.

In short, supporting crossbridge libraries is about the same, I just need to provide a compatible API by reviewing and patching: CModule.as, C_Run.as, AlcDbgHelper.as, etc.

In fact, in the original crossbridge github (the Adobe one, not the community one), you can see 3 essential files: ShellPosix.as, ShellPosixGlue.h and ShellPosixGlue.cpp.

Those implementations will have to change too, here an example in ShellPosixGlue.cpp

	int ShellPosixObject::open(int A_path, int A_flags, int A_mode, int errnoPtr) {
		char *A_path_ptr = (char *) domainMemoryPtr(this, A_path);
		int saved_err = errno;
		errno = 0;
		int ret = ::open(A_path_ptr, A_flags, A_mode);
		if (errno) {
			int *alc_errno = (int *) domainMemoryPtr(this, errnoPtr);
			*alc_errno = errno;
		}
		errno = saved_err;
		return ret;
	}

it would work โ€œas isโ€ in Redtamarin, but I already worked a lot on those native functions to make them cross-platform so the change woudl be like that

	int ShellPosixObject::open(int A_path, int A_flags, int A_mode, int errnoPtr) {
		char *A_path_ptr = (char *) domainMemoryPtr(this, A_path);
		int saved_err = errno;
		errno = 0;
		int ret = VMPI_open(A_path_ptr, A_flags, A_mode);
		if (errno) {
			int *alc_errno = (int *) domainMemoryPtr(this, errnoPtr);
			*alc_errno = errno;
		}
		errno = saved_err;
		return ret;
	}

from
int ret = ::open(A_path_ptr, A_flags, A_mode);
to
int ret = VMPI_open(A_path_ptr, A_flags, A_mode);

for the details, under linux and mac, the defintion is

#define VMPI_open         ::open

and under windows

#define VMPI_open         ::_open

It seems not much for a simple case, but there are more complicated case where it matters a lot to do like that.

Anyway, all that said, and even if it will take a while to put all that in place,
the plan (among other things) to support these glue libraries will also take into account crossbridge,
so not only dev would be able to port JS code and make it run inside Redtamarin but also C/C++ code.

here a little layout of those glue libs
(not in any order of priorities etc.)

  • AVMGlue
    library to support the Flash API and Adobe AIR API
    porting AS3 to AS3
  • ChakraGlue
    library to support the ChakraHost API
    porting JS to AS3
  • NodeGlue
    library to support the Node.js API
    porting JS to AS3
  • BrowserGlue
    library to support the Web Browser API
    porting JS to AS3
  • XCGlue
    library to support the CrossBridge API
    porting C/C++ to AS3

So yeah it is possible :slight_smile: