redtamarin logo

Redshell

The RedTamarin shell

Description

Redshell is the shell executable produced by the RedTamarin project.

6 versions are produced for each Operating Systems

  1. redshell
    32-bit release

  2. redshell_d
    32-bit debug

  3. redshell_dd
    32-bit debug debugger

  4. redshell
    64-bit release

  5. redshell_d
    64-bit debug

  6. redshell_dd
    64-bit debug debugger

For each release of the RedTamarin SDK
the project generate executable for Windows, Mac OS X and Linux.

The redshell is the core of the whole system, it allows us to

  • run and interpret
    ActionScript 3.0 files (uncompiled)
    ABC files (ActionScript ByteCode)
    SWF files (ShockWave Flash binaries)

  • setup versioning
    at the SWF level
    at the API level

  • be compatible with other AVM2 runtimes
    Adobe Flash Player
    Adobe AIR

  • embed our own cross-platform native API
    (what you can find in 'redtamarin.swc')

  • understand projector files
    (redshell merged with an ABC or SWF file)


Installation

All redshell are provided pre-compilled with the RedTamarin SDK

When you download the SDK for your operating system
you will find the redshell here

(sdk root)
   |_ ...
   |_ runtimes
        |_ redshell
               |_ {platform}    <- can be windows, macintosh, linux
                       |  
                       |_ 0.4.1T174        <- version tag
                       |
                       |_ 32               <- 32-bit versions
                       |   |_ redshell
                       |   |_ redshell_d
                       |   |_ redshell_dd
                       |
                       |_ 64                <- 64-bit versions
                           |_ redshell
                           |_ redshell_d
                           |_ redshell_dd

When you download the redshell release zip file

(zip root)
   |_ {platform}    <- can be windows, macintosh, linux
           |  
           |_ 0.4.1T174        <- version tag
           |
           |_ 32               <- 32-bit versions
           |   |_ redshell
           |   |_ redshell_d
           |   |_ redshell_dd
           |
           |_ 64                <- 64-bit versions
               |_ redshell
               |_ redshell_d
               |_ redshell_dd

Under Mac OS X and Linux

You will have to go into the folders containing the binaries
and make them executable for your system

for example

$ cd /sdk/redtamarin/runtimes/redshell/macintosh/32
$ chmod +x redshell*

$ cd /sdk/redtamarin/runtimes/redshell/macintosh/64
$ chmod +x redshell*

If you want to have access to the executable
on the command line you can link to them

$ cd /usr/bin
$ sudo ln -s /sdk/redtamarin/runtimes/redshell/macintosh/32/redshell redshell

or you can add them to your PATH

$ cd ~
$ sudo pico .profile
/*
export PATH=/sdk/redtamarin/runtimes/redshell/macintosh/32:$PATH;
*/

Our recommanded way to do that

  1. Create an environment variable named REDTAMARIN_SDK
    and add the bin folder to your path
$ cd ~
$ sudo pico .profile
/*
export REDTAMARIN_SDK=/sdk/redtamarin
export PATH=${REDTAMARIN_SDK}/bin:$PATH;
*/
  1. Create a symbolic link in the redtamarin bin folder
$ cd /sdk/redtamarin/bin
$ ln -s /sdk/redtamarin/runtimes/redshell/macintosh/32/redshell redshell

This way you can

  • Update the redtamarin SDK path
    with different versions

  • Update the redshell binary in the bin folder
    with either the release, debug or debug debugger version
    in either 32-bit or 64-bit

  • Have access to both redbean and redshell
    on your command line

Under Windows

The binaries should be executable by default because of the .exe extension.

If you want to have access to the executable
on the command line it will depends on which prompt you are using.

With a Cygwin bash prompt you can follow the same instructions
provided above for Macintosh and Linux.

With the "classic" Windows command prompt you will need
to either create shortcuts or copy one of the redhsell binary you want to use
in one of your system PATH or Path folders.

Our recommanded way is to use Cygwin.


Usage

Command line help

You must provide input files, -repl, or -Dselftest, or the executable must be a projector file.
avmplus shell 2.1 debug-debugger build cyclone

Description: redtamarin-0.4-beta[1T174]

usage: avmplus
          [-d]          enter debugger on start
          [-memstats]   generate statistics on memory usage
          [-memstats-verbose]
                        generate more statistics on memory usage
          [-memlimit d] limit the heap size to d pages
          [-eagersweep] sweep the heap synchronously at the end of GC;
                        improves usage statistics.
          [-gcbehavior] summarize GC behavior and policy, after every gc
          [-gcsummary]  summarize GC behavior and policy, at end only
          [-load L,B, ...
                        GC load factor L up to a post-GC heap size of B megabytes.
                        Up to 7 pairs can be accommodated, the limit for the last pair
                        will be ignored and can be omitted
          [-loadCeiling X] GC load multiplier ceiling (default 1.0)
          [-gcwork G]   Max fraction of time (default 0.25) we're willing to spend in GC
          [-stack N]    Stack size in bytes (will be honored approximately).
                        Be aware of the stack margin: 131072
          [-gcstack N]  Mark stack size allowance (# of segments), for testing.
          [-cache_bindings N]   size of bindings cache (0 = unlimited)
          [-cache_metadata N]   size of metadata cache (0 = unlimited)
          [-cache_methods  N]   size of method cache (0 = unlimited)
          [-Dgreedy]    collect before every allocation
          [-Dnogc]      don't collect (including DRC)
          [-Dnodrc]     don't use DRC (only use mark/sweep)
          [-Ddrcvalidation]     Perform a mark before each Reap to seek out reachable zero count items
          [-Dnoincgc]   don't use incremental collection
          [-Dnodebugger] do not initialize the debugger (in DEBUGGER builds)
          [-Dgcthreshold N] lower bound on allocation budget, in blocks, between collection completions
          [-Dnofixedcheck]  don't check FixedMalloc deallocations for correctness (sometimes expensive)
          [-Dastrace N] display AS execution information, where N is [1..4]
          [-Dlanguage l] localize runtime errors, languages are:
                        en,de,es,fr,it,ja,ko,zh-CN,zh-TW
          [-Dverbose[=[parse,verify,interp,traits,builtins,memstats,sweep,occupancy,execpolicy,jit,opt,regs,raw,bytes,lir,lircfg[-bb|-ins]]]
                        With no options, enables extreme! output mode.  Otherwise the
                        options are mostly self-descriptive except for the following: 
                           builtins - includes output from builtin methods
                           memstats - generate statistics on memory usage 
                           sweep - [memstats] include detailed sweep information 
                           occupancy - [memstats] include occupancy bit graph 
                           execpolicy - shows which execution method (interpretation, compilation) was chosen and why 
                           jit - output LIR as it is generated, and final assembly code
                           lir - [jit] only write out the LIR instructions
                           opt - [jit] show details about each optimization pass
                           regs - [jit] show register allocation state after each assembly instruction
                           raw - [jit] assembly code is displayed in raw (i.e unbuffered bottom-up) fashion. 
                           bytes - [jit] display the byte values of the assembly code. 
                           lircfg - [jit] write a gml representation of the LIR control-flow graph to a file.
                           lircfg-bb - [jit] same as above, but each vertex is a basic blocks rather than an EBBs.
                           lircfg-ins - [jit] same as above, but each vertex is an instruction.
                        Note that ordering matters for options with dependencies.  Dependencies 
                        are contained in [ ] For example, 'sweep' requires 'memstats' 
          [-Dverbose-only [{id|name|%regex%}]+ ]
                        enable verbose output only for the methods identified. Valid only for verify,interp and jit
                        options.  The method identification follows the same syntax as -policy (see below)
                        e.g. -Dverbose-only "Function/prime_val.as\$1:prime,%global%" 
          [-Dinterp]    do not generate machine code, interpret instead
          [-Ojit]       use jit always, never interp (except when the jit fails)
          [-Dcheckjitpageflags] check page protection flags on JIT memory allocation (sometimes expensive)
          [-Djitordie]  use jit always, and abort when the jit fails
          [-Dnocse]     disable CSE optimization
          [-Dnoinline]  disable speculative inlining
          [-jitharden]  enable jit hardening techniques
          [-osr=T]      enable OSR with invocation threshold T; disable with -osr=0; default is -osr=0
          [-prof=L]     enable jit profile level L; default 0=disabled; 1=function ranges, 2=functions+native asm)
          [-Dnosse]     use FPU stack instead of SSE2 instructions
          [-Dfixedesp]  pre-decrement stack for all needed call usage upon method entry
          [-policy [{interp|jit}={id|name|%regex%}]+ ]
                        override the default policy using method identifiers (see -Dverbose=execpolicy,builtins)
                        and/or method names and/or regular expressions. ids can be specified either
                        singly or as a range, while names will attempt to match exactly. regex follows
                        perl regular expression syntax. Note: rules are *not* checked for consistency
                        e.g. -Dverbose=execpolicy,builtins -policy "jit=%(avmshell)|(global)%,interp=Function/prime",jit=-3,interp=5-9,jit=42
          [-Dverifyall] verify greedily instead of lazily
          [-Dverifyonly] verify greedily and don't execute anything
          [-Dverifyquiet] verify greedily and don't execute anything w/o re-queue msgs
          [-Dselftest[=component,category,test]]
                        run selftests
          [-Dtimeout]   enforce maximum 15 seconds execution
          [-Dversion]   print the version and the list of compiled-in features and then exit
          [-repl]       read-eval-print mode
          [-workers W,T[,R]]
                        Spawn W worker VMs on T threads where W >= T and T >= 1.
                        The files provided are handed off to the workers in the order given,
                        as workers become available, and these workers are scheduled onto threads
                        in a deterministic order that prevents them from having affinity to a thread.
                        To test this functionality you want many more files than workers and many more
                        workers than threads, and at least two threads.
                        If R > 0 is provided then it is the number of times the list of files is repeated.
          [-swfHasAS3]  Exit with code 0 if the single file argument is a swf that contains a DoABC or DoABC2 tag,
                        otherwise exit with code 1.  Do not execute or verify anything.
          [-swfversion version]
                        Run with a given bug-compatibility version in use by default.
                        (This can be overridden on a per-ABC basis by embedded metadata.)
                        Legal versions are:
                            9
                            10
                            11
                            12
                            13
                            14
                            15
                            16
                            17
                            18
                            19
          [-log]
          [-api N] execute ABCs as version N (see api-versions.h)
          [filename.{abc,swf} ...
          [-- application argument ...]

Run ActionScript 3.0 files

You can run .as files (uncompiled)

$ ./redshell test.as

(yes even if the help indicate only "filename.{abc,swf}")

When provided with an .as file
the redshell will automatically try to evaluate it
with its internal eval engine.

From that script you can access most of the RedTamarin API.

for example:

import C.unistd.*;

trace( "username = " + getlogin() );

If you need to provide arguments to the script you can do

$ ./redshell test.as -- -a -b -c

and get access to them like this

import shell.Program;

trace( "args = " + Program.argv ); // args = -a,-b,-c
The eval engine can be confused to which definitions
it can access from your script.

Sometimes, some variables, functions, classes can not be accessed
because the eval engine think they are not declared.

A workaround is to use code reflection with the any type

// if doing the following generate an error
// import test.MyClass;
// 
// getClassByName() is a TopLevel function
// and so does not need to be imported
var MyClass:Class = getClassByName( "test.MyClass" );

// do not type the instance
var test:* = new MyClass(); // the * is the any type
shebang scripts are not supported.

eg. if you write a script with a shebang

#!/usr/bin/redshell

trace( "hello world");

The eval engine will output an error
because of the shebang line.

Run ActionScript ByteCode files

You can run .abc files (compiled)

$ ./redshell test.abc

To procude an ABC file you will need to use the ActionScript Compiler (ASC)

# produce test.abc
$ java -jar asc.jar -AS3 -strict -md -import redtamarin.abc test.as

to be able to use the RedTamarin API in your code
you will need to import the redtamarin.abc.

If you need to provide arguments to an ABC file you can do

$ ./redshell test.abc -- -a -b -c

If you need to run more than one ABC files you can do

$ ./redshell lib1.abc lib2.abc test.abc

only the last one will "execute"

The ActionScript Compiler (ASC) does not work like
the MXML Compiler (MXMLC) used with Flash/AIR

You will have to manage include files by hand.

for example:

include "test/MyClass.as";
include "test/MyOtherClass.as";

import test.MyClass;

var test:MyClass = new MyClass();

Run ShockWave Flash files

You can run .swf files (compiled)

$ ./redshell test.swf
Only the SWF tags DoABC and DoABC2 will be read
any other SWF tags will be ignored.
SWF files compiled with MXMLC with dependencies
on playerglobal or airglobal
will most likely generate errors
ans can not be understood by the redshell "as is"

SWF files are used as way to "zip" ABC files together

so instead of doing this

$ ./redshell lib1.abc lib2.abc test.abc

we can simply do this

$ ./redshell test.swf

with

test.swf
   |_ lib1.abc
   |_ lib2.abc
   |_ test.abc

Details

More informations about the tool

Versioning

The redshell run with a SWF version and an API version
which allow to have functionalities available or not.

The way we define the RedTamarin API, this one will be available
with any versions of either the SWF or API.

Some of our API, in AVMGlue, that try to replicate the behaviour
of the Flash Platform API do use versioning.

for example:
In the class ByteArray the getter/setter shareable
is only available to Flash Player 11.4 and AIR 3.4.

If one of your script access this property and you are running the redshell with

$ ./redshell_dd -api SWF_13 test.abc

SWF_13 is for the API of Flash Player 11.0
a lower version of the API than the one needed (11.4)

then you will obtain a ReferenceError

ReferenceError: Error #1069: Property shareable not found on flash.utils.ByteArray and there is no default value.

To avoid this error you would need to use the minimum API version

$ ./redshell_dd -api SWF_17 test.abc

SWF_17 is for the API of Flash Player 11.4

Read Eval Print mode

You can run the redshel in read-eval-print mode

$ ./redshell_dd -repl

from that point you will enter the interactive shell

avmplus interactive shell
Type '?' for help

> ?
Text entered at the prompt is compiled and evaluated unless
it is one of these commands:

  ?             print help
  .input        collect lines until a line that reads '.end',
                then eval the collected lines
  .load file    load the file (source or compiled)
  .quit         leave the repl
  .time expr    evaluate expr and report the time it took.

> .quit

More Shells

Currently we produce 18 redshell executables
(6 for Windows, 6 for Mac OS X and 6 for Linux).

With more ressources we could produce even more:

  • Mac OS PPC
  • Windows CE
  • Sun Solaris
  • SH4
  • Android
  • ARM
  • etc.

The RedTamarin sources are already setup to support those different architectures,
the native API have not been ported or tested there though, but if a champion
or sponsor of a particular system were to help we could with not too much
trouble add such build to generate those executables.

For the time being we decide to focus only

  • Windows
    we test with Windows 7 Ultimate 64-bit
    the redshell should work with

    • Windows 2000
    • Windows XP
    • Windows 2003
    • Windows 2008
    • Windows 8
    • etc.
  • Macintosh
    We test with Mac OS X 10.8 64-bit
    the redshell should work with

    • mac OS X 10.7
    • mac OS X 10.8
    • mac OS X 10.9
    • mac OS X 10.10
    • etc.
  • Linux
    we test with Ubuntu Desktop 10.04 64-bit
    the redshell should work with

    • Ubuntu 8, 9, 10, 11, 12, 13, 14
    • Debian
    • CentOS
    • (other Linux distros)
    • etc.

History

Under the Tamarin project this executable was either named avmshell or avmplus,
and the tool was ment as a debugging and testing environment (for the Flash Player runtime),
which can explain the numerous and advanced command line parameters.

In a previous version of the redshell we made some change on how those parameters
were interpreted, if the redshell was a projector for example, we would ignore other parameters
to avoid to have to use the -- to pass user provided arguments to the projector.

We reverted that for the time being, only changes we made to the original avmshell
are changes related to the execution of the native API, for example:
a hook to intercept the exit() function and other little things.

RedTamarin and the redshell are still a young project, we are exploring different way
to make all that more practical and efficient.


Copyright 2017 zwetan

Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.