master 44ffa1b0bb5f cached
17 files
127.4 KB
38.6k tokens
122 symbols
1 requests
Download .txt
Repository: irelance/jsc-decompile-mozjs-34
Branch: master
Commit: 44ffa1b0bb5f
Files: 17
Total size: 127.4 KB

Directory structure:
gitextract_il3n6s28/

├── .gitignore
├── composer.json
├── readme.md
├── run.php
├── scan.php
└── src/
    ├── Constant.php
    ├── Context.php
    ├── Decompile.php
    ├── Helper/
    │   ├── Operation.php
    │   ├── Reveal.php
    │   └── Stack.php
    └── Xdr/
        ├── Atom.php
        ├── Common.php
        ├── ObjectXdr.php
        ├── Operation.php
        ├── Scope.php
        └── Script.php

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
js/
compile
libmozglue.dylib
libmozjs-52.dylib
.idea/

/vendor/
composer.lock


================================================
FILE: composer.json
================================================
{
    "name": "irelance/jsc-decompile-mozjs-34",
    "license": "proprietary",
    "type": "project",
    "authors": [
        {
            "name": "irelance",
            "email": "heirelance@163.com"
        }
    ],
    "autoload": {
        "psr-4": {
            "Irelance\\Mozjs34\\": "src"
        }
    },
    "require": {
        "php": ">=7.0.0"
    }
}


================================================
FILE: readme.md
================================================
# 1.Summary

This project is a javascript bytecode decoder for mozilla spider-monkey version 34.

This version may decompile jsc file compile by cocos-2dx.

It would not work for different version of Mozilla spider-monkey (without shell of course), for its opcode defined different for each version.

Maybe no longer update, but still a good example to understand how javascript virtual machine work (though different engine has different implement).

Is this project can just decompile "34" version only and why?

Well, the truth is may decompile near 34 version before bytecode file structure change.

Js engine may change the file struct for support new language feather, performance optimization, code refactoring, ...

But think of most change is just to add ```section```(concept come of executable binary file) and add ```operation``` instead of change struct.

So this project just try to decompile without check magic code. At least, scan.php will work at most time.

# 2.Usage

## 2.1.Install PHP and Composer

If you are familiar with php, you can skip this part.

install php7.0 (still work in php7.4)
```
# ubuntu
$ sudo apt install php7.0

# mac
$ brew install php7.0

# windows
# just google an binary one
```
install composer
>see https://getcomposer.org/download/

install this project
```
$ cd path/to/project
# no dependences, just auto generate the autoload
$ composer install
```

## 2.2.decompile *.jsc file

```
$ cd /path/to/this/project
$ php run.php /path/to/your.jsc > /path/to/decompile.txt
#if this didn't work, you can also try below command to get the bitcode
$ php scan.php /path/to/your.jsc > /path/to/scan.txt
```

## 2.3. print more info with scan.php

Just remove the slashes in scan.php

# 3. How to guess the bytecode version

| magic code  |  version  |
|    ---      |    ---    |
| 2C C0 73 B9 |     33    |
| 28 C0 73 B9 |     34    |
| 25 C0 73 B9 |     35    |
| 04 C0 73 B9 |     36    |
| FC BF 73 B9 |     37    |
| F4 BF 73 B9 |     38    |
| D1 BF 73 B9 |     39    |
| C3 BF 73 B9 |     40    |
| B7 BF 73 B9 |     41    |
| B3 BF 73 B9 |     42    |
| AB BF 73 B9 |     43    |
| A0 BF 73 B9 |     44    |
| 95 BF 73 B9 |     45    |
| 88 BF 73 B9 |     46    |
| 81 BF 73 B9 |     47    |

Yes, change happens >= 48.
bytecodeVer(int) change to buildId(string).
And buildId is very like an useragent of browser.

# 4.Besides

This project is not complete yet.

- A Fatal Bug was found when decompile with a deep context

Decompile result is not a runable file.
Some local variables are auto generate, for the compiler discards local variables.



================================================
FILE: run.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/1
 * Time: 上午10:47
 */
include 'vendor/autoload.php';


$decompile = new Irelance\Mozjs34\Decompile($argv[1]);
$decompile->run();
//$decompile->runResult();
$contexts = $decompile->getContexts();
foreach ($contexts as $index => $context) {
    //if ($index==0) {
        echo '==================================' . $index . '==================================S', CLIENT_EOL;
        /* @var \Irelance\Mozjs34\Context $context */
        $context->printProperties([
            //'Summaries',
            //'Atoms',
            //'Operations',
            'Argv',
            'Content',
            //'Nodes',
            //'Consts',
            //'Objects',
            //'Regexps',
            //'TryNote',
            //'ScopeNote',
        ]);
        echo '==========================================================================E', CLIENT_EOL;
    //}
}


================================================
FILE: scan.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2018/10/10
 * Time: 17:51
 */

include 'vendor/autoload.php';


$decompile = new Irelance\Mozjs34\Decompile($argv[1]);
$decompile->run();
//$decompile->runResult();
$contexts = $decompile->getContexts();
foreach ($contexts as $index => $context) {
    //if ($index==0) {
    echo '==================================' . $index . '==================================S', CLIENT_EOL;
    /* @var \Irelance\Mozjs34\Context $context */
    $context->printProperties([
        //'Summaries',
        'Atoms',
        'Operations',
        'Argv',
        //'Content',
        'Nodes',
        'Consts',
        //'Objects',
        'Regexps',
        //'TryNote',
        //'ScopeNote',
    ]);
    echo '==========================================================================E', CLIENT_EOL;
    //}
}

================================================
FILE: src/Constant.php
================================================
<?php

/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/9/30
 * Time: 上午10:05
 */
namespace Irelance\Mozjs34;
if (php_sapi_name() == 'cli') {
    define('CLIENT_EOL', PHP_EOL);
} else {
    define('CLIENT_EOL', "<br>");
}

define('JSID_TYPE_STRING', 0x0);
define('JSID_TYPE_INT', 0x1);
define('JSID_TYPE_VOID', 0x2);
define('JSID_TYPE_SYMBOL', 0x4);
define('JSID_TYPE_MASK', 0x7);

define("js_undefined_str", "undefined");
define("js_typeof_str", "typeof");
define("js_void_str", "void");
define("js_null_str", "null");
define("js_false_str", "false");
define("js_true_str", "true");
define("js_throw_str", "throw");
define("js_in_str", "in");
define("js_instanceof_str", "instanceof");
define("js_this_str", "this");
define("js_new_str", "new");

class Constant
{
    const _ConstTag = [
        'SCRIPT_INT',
        'SCRIPT_DOUBLE',
        'SCRIPT_ATOM',
        'SCRIPT_TRUE',
        'SCRIPT_FALSE',
        'SCRIPT_NULL',
        'SCRIPT_OBJECT',
        'SCRIPT_VOID',
        'SCRIPT_HOLE',
    ];

    const _Class = [
        'CK_BlockObject',
        'CK_WithObject',
        'CK_JSFunction',
        'CK_JSObject'
    ];

    const _ScriptBits = [
        'NoScriptRval',
        'SavedCallerFun',
        'Strict',
        'ContainsDynamicNameAccess',
        'FunHasExtensibleScope',
        'FunNeedsDeclEnvObject',
        'FunHasAnyAliasedFormal',
        'ArgumentsHasVarBinding',
        'NeedsArgsObj',
        'IsGeneratorExp',
        'IsLegacyGenerator',
        'IsStarGenerator',
        'OwnSource',
        'ExplicitUseStrict',
        'SelfHosted',
        'IsCompileAndGo',
        'HasSingleton',
        'TreatAsRunOnce',
        'HasLazyScript'
    ];

    const _FirstWordFlag = [
        'HasAtom' => 0x1,
        'IsStarGenerator' => 0x2,
        'IsLazy' => 0x4,
        'HasSingletonType' => 0x8
    ];

    const _Opcode = [
        0 => ['op' => 'JSOP_NOP', 'val' => 0, 'name' => "nop", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        1 => ['op' => 'JSOP_UNDEFINED', 'val' => 1, 'name' => js_undefined_str, 'image' => "", 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        2 => ['op' => 'JSOP_UNUSED2', 'val' => 2, 'name' => "unused2", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 0, 'format' => ['JOF_BYTE']],
        3 => ['op' => 'JSOP_ENTERWITH', 'val' => 3, 'name' => "enterwith", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 0, 'format' => ['JOF_OBJECT']],
        4 => ['op' => 'JSOP_LEAVEWITH', 'val' => 4, 'name' => "leavewith", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        5 => ['op' => 'JSOP_RETURN', 'val' => 5, 'name' => "return", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 0, 'format' => ['JOF_BYTE']],
        6 => ['op' => 'JSOP_GOTO', 'val' => 6, 'name' => "goto", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 0, 'format' => ['JOF_JUMP']],
        7 => ['op' => 'JSOP_IFEQ', 'val' => 7, 'name' => "ifeq", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 0, 'format' => ['JOF_JUMP', 'JOF_DETECTING']],
        8 => ['op' => 'JSOP_IFNE', 'val' => 8, 'name' => "ifne", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 0, 'format' => ['JOF_JUMP']],
        9 => ['op' => 'JSOP_ARGUMENTS', 'val' => 9, 'name' => "arguments", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        10 => ['op' => 'JSOP_SWAP', 'val' => 10, 'name' => "swap", 'image' => NULL, 'len' => 1, 'use' => 2, 'def' => 2, 'format' => ['JOF_BYTE']],
        11 => ['op' => 'JSOP_POPN', 'val' => 11, 'name' => "popn", 'image' => NULL, 'len' => 3, 'use' => -1, 'def' => 0, 'format' => ['JOF_UINT16']],
        12 => ['op' => 'JSOP_DUP', 'val' => 12, 'name' => "dup", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 2, 'format' => ['JOF_BYTE']],
        13 => ['op' => 'JSOP_DUP2', 'val' => 13, 'name' => "dup2", 'image' => NULL, 'len' => 1, 'use' => 2, 'def' => 4, 'format' => ['JOF_BYTE']],
        14 => ['op' => 'JSOP_SETCONST', 'val' => 14, 'name' => "setconst", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_SET']],
        15 => ['op' => 'JSOP_BITOR', 'val' => 15, 'name' => "bitor", 'image' => "|", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        16 => ['op' => 'JSOP_BITXOR', 'val' => 16, 'name' => "bitxor", 'image' => "^", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        17 => ['op' => 'JSOP_BITAND', 'val' => 17, 'name' => "bitand", 'image' => "&", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        18 => ['op' => 'JSOP_EQ', 'val' => 18, 'name' => "eq", 'image' => "==", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH', 'JOF_DETECTING']],
        19 => ['op' => 'JSOP_NE', 'val' => 19, 'name' => "ne", 'image' => "!=", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH', 'JOF_DETECTING']],
        20 => ['op' => 'JSOP_LT', 'val' => 20, 'name' => "lt", 'image' => "<", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        21 => ['op' => 'JSOP_LE', 'val' => 21, 'name' => "le", 'image' => "<=", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        22 => ['op' => 'JSOP_GT', 'val' => 22, 'name' => "gt", 'image' => ">", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        23 => ['op' => 'JSOP_GE', 'val' => 23, 'name' => "ge", 'image' => ">=", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        24 => ['op' => 'JSOP_LSH', 'val' => 24, 'name' => "lsh", 'image' => "<<", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        25 => ['op' => 'JSOP_RSH', 'val' => 25, 'name' => "rsh", 'image' => ">>", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        26 => ['op' => 'JSOP_URSH', 'val' => 26, 'name' => "ursh", 'image' => ">>>", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        27 => ['op' => 'JSOP_ADD', 'val' => 27, 'name' => "add", 'image' => "+", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        28 => ['op' => 'JSOP_SUB', 'val' => 28, 'name' => "sub", 'image' => "-", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        29 => ['op' => 'JSOP_MUL', 'val' => 29, 'name' => "mul", 'image' => "*", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        30 => ['op' => 'JSOP_DIV', 'val' => 30, 'name' => "div", 'image' => "/", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        31 => ['op' => 'JSOP_MOD', 'val' => 31, 'name' => "mod", 'image' => "%", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        32 => ['op' => 'JSOP_NOT', 'val' => 32, 'name' => "not", 'image' => "!", 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ARITH', 'JOF_DETECTING']],
        33 => ['op' => 'JSOP_BITNOT', 'val' => 33, 'name' => "bitnot", 'image' => "~", 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ARITH']],
        34 => ['op' => 'JSOP_NEG', 'val' => 34, 'name' => "neg", 'image' => "- ", 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ARITH']],
        35 => ['op' => 'JSOP_POS', 'val' => 35, 'name' => "pos", 'image' => "+ ", 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ARITH']],
        36 => ['op' => 'JSOP_DELNAME', 'val' => 36, 'name' => "delname", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME']],
        37 => ['op' => 'JSOP_DELPROP', 'val' => 37, 'name' => "delprop", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP']],
        38 => ['op' => 'JSOP_DELELEM', 'val' => 38, 'name' => "delelem", 'image' => NULL, 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ELEM']],
        39 => ['op' => 'JSOP_TYPEOF', 'val' => 39, 'name' => js_typeof_str, 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_DETECTING']],
        40 => ['op' => 'JSOP_VOID', 'val' => 40, 'name' => js_void_str, 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE']],
        41 => ['op' => 'JSOP_SPREADCALL', 'val' => 41, 'name' => "spreadcall", 'image' => NULL, 'len' => 1, 'use' => 3, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_INVOKE', 'JOF_TYPESET']],
        42 => ['op' => 'JSOP_SPREADNEW', 'val' => 42, 'name' => "spreadnew", 'image' => NULL, 'len' => 1, 'use' => 3, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_INVOKE', 'JOF_TYPESET']],
        43 => ['op' => 'JSOP_SPREADEVAL', 'val' => 43, 'name' => "spreadeval", 'image' => NULL, 'len' => 1, 'use' => 3, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_INVOKE', 'JOF_TYPESET']],
        44 => ['op' => 'JSOP_DUPAT', 'val' => 44, 'name' => "dupat", 'image' => NULL, 'len' => 4, 'use' => 0, 'def' => 1, 'format' => ['JOF_UINT24']],
        45 => ['op' => 'JSOP_UNUSED45', 'val' => 45, 'name' => "unused45", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        46 => ['op' => 'JSOP_UNUSED46', 'val' => 46, 'name' => "unused46", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        47 => ['op' => 'JSOP_UNUSED47', 'val' => 47, 'name' => "unused47", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        48 => ['op' => 'JSOP_UNUSED48', 'val' => 48, 'name' => "unused48", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        49 => ['op' => 'JSOP_UNUSED49', 'val' => 49, 'name' => "unused49", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        50 => ['op' => 'JSOP_UNUSED50', 'val' => 50, 'name' => "unused50", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        51 => ['op' => 'JSOP_UNUSED51', 'val' => 51, 'name' => "unused51", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        52 => ['op' => 'JSOP_UNUSED52', 'val' => 52, 'name' => "unused52", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        53 => ['op' => 'JSOP_GETPROP', 'val' => 53, 'name' => "getprop", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP', 'JOF_TYPESET', 'JOF_TMPSLOT3']],
        54 => ['op' => 'JSOP_SETPROP', 'val' => 54, 'name' => "setprop", 'image' => NULL, 'len' => 5, 'use' => 2, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP', 'JOF_SET', 'JOF_DETECTING']],
        55 => ['op' => 'JSOP_GETELEM', 'val' => 55, 'name' => "getelem", 'image' => NULL, 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ELEM', 'JOF_TYPESET', 'JOF_LEFTASSOC']],
        56 => ['op' => 'JSOP_SETELEM', 'val' => 56, 'name' => "setelem", 'image' => NULL, 'len' => 1, 'use' => 3, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ELEM', 'JOF_SET', 'JOF_DETECTING']],
        57 => ['op' => 'JSOP_UNUSED57', 'val' => 57, 'name' => "unused57", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        58 => ['op' => 'JSOP_CALL', 'val' => 58, 'name' => "call", 'image' => NULL, 'len' => 3, 'use' => -1, 'def' => 1, 'format' => ['JOF_UINT16', 'JOF_INVOKE', 'JOF_TYPESET']],
        59 => ['op' => 'JSOP_NAME', 'val' => 59, 'name' => "name", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_TYPESET']],
        60 => ['op' => 'JSOP_DOUBLE', 'val' => 60, 'name' => "double", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_DOUBLE']],
        61 => ['op' => 'JSOP_STRING', 'val' => 61, 'name' => "string", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM']],
        62 => ['op' => 'JSOP_ZERO', 'val' => 62, 'name' => "zero", 'image' => "0", 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        63 => ['op' => 'JSOP_ONE', 'val' => 63, 'name' => "one", 'image' => "1", 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        64 => ['op' => 'JSOP_NULL', 'val' => 64, 'name' => js_null_str, 'image' => js_null_str, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        65 => ['op' => 'JSOP_THIS', 'val' => 65, 'name' => js_this_str, 'image' => js_this_str, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        66 => ['op' => 'JSOP_FALSE', 'val' => 66, 'name' => js_false_str, 'image' => js_false_str, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        67 => ['op' => 'JSOP_TRUE', 'val' => 67, 'name' => js_true_str, 'image' => js_true_str, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        68 => ['op' => 'JSOP_OR', 'val' => 68, 'name' => "or", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_JUMP', 'JOF_DETECTING', 'JOF_LEFTASSOC']],
        69 => ['op' => 'JSOP_AND', 'val' => 69, 'name' => "and", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_JUMP', 'JOF_DETECTING', 'JOF_LEFTASSOC']],
        70 => ['op' => 'JSOP_TABLESWITCH', 'val' => 70, 'name' => "tableswitch", 'image' => NULL, 'len' => -1, 'use' => 1, 'def' => 0, 'format' => ['JOF_TABLESWITCH', 'JOF_DETECTING']],
        71 => ['op' => 'JSOP_RUNONCE', 'val' => 71, 'name' => "runonce", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        72 => ['op' => 'JSOP_STRICTEQ', 'val' => 72, 'name' => "stricteq", 'image' => "===", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_DETECTING', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        73 => ['op' => 'JSOP_STRICTNE', 'val' => 73, 'name' => "strictne", 'image' => "!==", 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_DETECTING', 'JOF_LEFTASSOC', 'JOF_ARITH']],
        74 => ['op' => 'JSOP_SETCALL', 'val' => 74, 'name' => "setcall", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        75 => ['op' => 'JSOP_ITER', 'val' => 75, 'name' => "iter", 'image' => NULL, 'len' => 2, 'use' => 1, 'def' => 1, 'format' => ['JOF_UINT8']],
        76 => ['op' => 'JSOP_MOREITER', 'val' => 76, 'name' => "moreiter", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 2, 'format' => ['JOF_BYTE']],
        77 => ['op' => 'JSOP_ITERNEXT', 'val' => 77, 'name' => "iternext", 'image' => "<next>", 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        78 => ['op' => 'JSOP_ENDITER', 'val' => 78, 'name' => "enditer", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 0, 'format' => ['JOF_BYTE']],
        79 => ['op' => 'JSOP_FUNAPPLY', 'val' => 79, 'name' => "funapply", 'image' => NULL, 'len' => 3, 'use' => -1, 'def' => 1, 'format' => ['JOF_UINT16', 'JOF_INVOKE', 'JOF_TYPESET']],
        80 => ['op' => 'JSOP_OBJECT', 'val' => 80, 'name' => "object", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_OBJECT']],
        81 => ['op' => 'JSOP_POP', 'val' => 81, 'name' => "pop", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 0, 'format' => ['JOF_BYTE']],
        82 => ['op' => 'JSOP_NEW', 'val' => 82, 'name' => js_new_str, 'image' => NULL, 'len' => 3, 'use' => -1, 'def' => 1, 'format' => ['JOF_UINT16', 'JOF_INVOKE', 'JOF_TYPESET']],
        83 => ['op' => 'JSOP_UNUSED83', 'val' => 83, 'name' => "unused83", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        84 => ['op' => 'JSOP_GETARG', 'val' => 84, 'name' => "getarg", 'image' => NULL, 'len' => 3, 'use' => 0, 'def' => 1, 'format' => ['JOF_QARG', 'JOF_NAME']],
        85 => ['op' => 'JSOP_SETARG', 'val' => 85, 'name' => "setarg", 'image' => NULL, 'len' => 3, 'use' => 1, 'def' => 1, 'format' => ['JOF_QARG', 'JOF_NAME', 'JOF_SET']],
        86 => ['op' => 'JSOP_GETLOCAL', 'val' => 86, 'name' => "getlocal", 'image' => NULL, 'len' => 4, 'use' => 0, 'def' => 1, 'format' => ['JOF_LOCAL', 'JOF_NAME']],
        87 => ['op' => 'JSOP_SETLOCAL', 'val' => 87, 'name' => "setlocal", 'image' => NULL, 'len' => 4, 'use' => 1, 'def' => 1, 'format' => ['JOF_LOCAL', 'JOF_NAME', 'JOF_SET', 'JOF_DETECTING']],
        88 => ['op' => 'JSOP_UINT16', 'val' => 88, 'name' => "uint16", 'image' => NULL, 'len' => 3, 'use' => 0, 'def' => 1, 'format' => ['JOF_UINT16']],
        89 => ['op' => 'JSOP_NEWINIT', 'val' => 89, 'name' => "newinit", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_UINT8']],
        90 => ['op' => 'JSOP_NEWARRAY', 'val' => 90, 'name' => "newarray", 'image' => NULL, 'len' => 4, 'use' => 0, 'def' => 1, 'format' => ['JOF_UINT24']],
        91 => ['op' => 'JSOP_NEWOBJECT', 'val' => 91, 'name' => "newobject", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_OBJECT']],
        92 => ['op' => 'JSOP_ENDINIT', 'val' => 92, 'name' => "endinit", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        93 => ['op' => 'JSOP_INITPROP', 'val' => 93, 'name' => "initprop", 'image' => NULL, 'len' => 5, 'use' => 2, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP', 'JOF_SET', 'JOF_DETECTING']],
        94 => ['op' => 'JSOP_INITELEM', 'val' => 94, 'name' => "initelem", 'image' => NULL, 'len' => 1, 'use' => 3, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ELEM', 'JOF_SET', 'JOF_DETECTING']],
        95 => ['op' => 'JSOP_INITELEM_INC', 'val' => 95, 'name' => "initelem_inc", 'image' => NULL, 'len' => 1, 'use' => 3, 'def' => 2, 'format' => ['JOF_BYTE', 'JOF_ELEM', 'JOF_SET']],
        96 => ['op' => 'JSOP_INITELEM_ARRAY', 'val' => 96, 'name' => "initelem_array", 'image' => NULL, 'len' => 4, 'use' => 2, 'def' => 1, 'format' => ['JOF_UINT24', 'JOF_ELEM', 'JOF_SET', 'JOF_DETECTING']],
        97 => ['op' => 'JSOP_INITPROP_GETTER', 'val' => 97, 'name' => "initprop_getter", 'image' => NULL, 'len' => 5, 'use' => 2, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP', 'JOF_SET', 'JOF_DETECTING']],
        98 => ['op' => 'JSOP_INITPROP_SETTER', 'val' => 98, 'name' => "initprop_setter", 'image' => NULL, 'len' => 5, 'use' => 2, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP', 'JOF_SET', 'JOF_DETECTING']],
        99 => ['op' => 'JSOP_INITELEM_GETTER', 'val' => 99, 'name' => "initelem_getter", 'image' => NULL, 'len' => 1, 'use' => 3, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ELEM', 'JOF_SET', 'JOF_DETECTING']],
        100 => ['op' => 'JSOP_INITELEM_SETTER', 'val' => 100, 'name' => "initelem_setter", 'image' => NULL, 'len' => 1, 'use' => 3, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ELEM', 'JOF_SET', 'JOF_DETECTING']],
        101 => ['op' => 'JSOP_CALLSITEOBJ', 'val' => 101, 'name' => "callsiteobj", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_OBJECT']],
        102 => ['op' => 'JSOP_NEWARRAY_COPYONWRITE', 'val' => 102, 'name' => "newarray_copyonwrite", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_OBJECT']],
        103 => ['op' => 'JSOP_UNUSED103', 'val' => 103, 'name' => "unused103", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        104 => ['op' => 'JSOP_UNUSED104', 'val' => 104, 'name' => "unused104", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        105 => ['op' => 'JSOP_UNUSED105', 'val' => 105, 'name' => "unused105", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        106 => ['op' => 'JSOP_LABEL', 'val' => 106, 'name' => "label", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 0, 'format' => ['JOF_JUMP']],
        107 => ['op' => 'JSOP_UNUSED107', 'val' => 107, 'name' => "unused107", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        108 => ['op' => 'JSOP_FUNCALL', 'val' => 108, 'name' => "funcall", 'image' => NULL, 'len' => 3, 'use' => -1, 'def' => 1, 'format' => ['JOF_UINT16', 'JOF_INVOKE', 'JOF_TYPESET']],
        109 => ['op' => 'JSOP_LOOPHEAD', 'val' => 109, 'name' => "loophead", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        110 => ['op' => 'JSOP_BINDNAME', 'val' => 110, 'name' => "bindname", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_SET']],
        111 => ['op' => 'JSOP_SETNAME', 'val' => 111, 'name' => "setname", 'image' => NULL, 'len' => 5, 'use' => 2, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_SET', 'JOF_DETECTING']],
        112 => ['op' => 'JSOP_THROW', 'val' => 112, 'name' => js_throw_str, 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 0, 'format' => ['JOF_BYTE']],
        113 => ['op' => 'JSOP_IN', 'val' => 113, 'name' => js_in_str, 'image' => js_in_str, 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC']],
        114 => ['op' => 'JSOP_INSTANCEOF', 'val' => 114, 'name' => js_instanceof_str, 'image' => js_instanceof_str, 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_LEFTASSOC', 'JOF_TMPSLOT']],
        115 => ['op' => 'JSOP_DEBUGGER', 'val' => 115, 'name' => "debugger", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        116 => ['op' => 'JSOP_GOSUB', 'val' => 116, 'name' => "gosub", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 0, 'format' => ['JOF_JUMP']],
        117 => ['op' => 'JSOP_RETSUB', 'val' => 117, 'name' => "retsub", 'image' => NULL, 'len' => 1, 'use' => 2, 'def' => 0, 'format' => ['JOF_BYTE']],
        118 => ['op' => 'JSOP_EXCEPTION', 'val' => 118, 'name' => "exception", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        119 => ['op' => 'JSOP_LINENO', 'val' => 119, 'name' => "lineno", 'image' => NULL, 'len' => 3, 'use' => 0, 'def' => 0, 'format' => ['JOF_UINT16']],
        120 => ['op' => 'JSOP_CONDSWITCH', 'val' => 120, 'name' => "condswitch", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        121 => ['op' => 'JSOP_CASE', 'val' => 121, 'name' => "case", 'image' => NULL, 'len' => 5, 'use' => 2, 'def' => 1, 'format' => ['JOF_JUMP']],
        122 => ['op' => 'JSOP_DEFAULT', 'val' => 122, 'name' => "default", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 0, 'format' => ['JOF_JUMP']],
        123 => ['op' => 'JSOP_EVAL', 'val' => 123, 'name' => "eval", 'image' => NULL, 'len' => 3, 'use' => -1, 'def' => 1, 'format' => ['JOF_UINT16', 'JOF_INVOKE', 'JOF_TYPESET']],
        124 => ['op' => 'JSOP_UNUSED124', 'val' => 124, 'name' => "unused124", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        125 => ['op' => 'JSOP_UNUSED125', 'val' => 125, 'name' => "unused125", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        126 => ['op' => 'JSOP_UNUSED126', 'val' => 126, 'name' => "unused126", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        127 => ['op' => 'JSOP_DEFFUN', 'val' => 127, 'name' => "deffun", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 0, 'format' => ['JOF_OBJECT']],
        128 => ['op' => 'JSOP_DEFCONST', 'val' => 128, 'name' => "defconst", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 0, 'format' => ['JOF_ATOM']],
        129 => ['op' => 'JSOP_DEFVAR', 'val' => 129, 'name' => "defvar", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 0, 'format' => ['JOF_ATOM']],
        130 => ['op' => 'JSOP_LAMBDA', 'val' => 130, 'name' => "lambda", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_OBJECT']],
        131 => ['op' => 'JSOP_LAMBDA_ARROW', 'val' => 131, 'name' => "lambda_arrow", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_OBJECT']],
        132 => ['op' => 'JSOP_CALLEE', 'val' => 132, 'name' => "callee", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        133 => ['op' => 'JSOP_PICK', 'val' => 133, 'name' => "pick", 'image' => NULL, 'len' => 2, 'use' => 0, 'def' => 0, 'format' => ['JOF_UINT8', 'JOF_TMPSLOT2']],
        134 => ['op' => 'JSOP_TRY', 'val' => 134, 'name' => "try", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        135 => ['op' => 'JSOP_FINALLY', 'val' => 135, 'name' => "finally", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 2, 'format' => ['JOF_BYTE']],
        136 => ['op' => 'JSOP_GETALIASEDVAR', 'val' => 136, 'name' => "getaliasedvar", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_SCOPECOORD', 'JOF_NAME', 'JOF_TYPESET']],
        137 => ['op' => 'JSOP_SETALIASEDVAR', 'val' => 137, 'name' => "setaliasedvar", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_SCOPECOORD', 'JOF_NAME', 'JOF_SET', 'JOF_DETECTING']],
        138 => ['op' => 'JSOP_UNUSED138', 'val' => 138, 'name' => "unused138", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        139 => ['op' => 'JSOP_UNUSED139', 'val' => 139, 'name' => "unused139", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        140 => ['op' => 'JSOP_UNUSED140', 'val' => 140, 'name' => "unused140", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        141 => ['op' => 'JSOP_UNUSED141', 'val' => 141, 'name' => "unused141", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        142 => ['op' => 'JSOP_UNUSED142', 'val' => 142, 'name' => "unused142", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        143 => ['op' => 'JSOP_GETINTRINSIC', 'val' => 143, 'name' => "getintrinsic", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_TYPESET']],
        144 => ['op' => 'JSOP_SETINTRINSIC', 'val' => 144, 'name' => "setintrinsic", 'image' => NULL, 'len' => 5, 'use' => 2, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_SET', 'JOF_DETECTING']],
        145 => ['op' => 'JSOP_BINDINTRINSIC', 'val' => 145, 'name' => "bindintrinsic", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_SET']],
        146 => ['op' => 'JSOP_UNUSED146', 'val' => 146, 'name' => "unused146", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        147 => ['op' => 'JSOP_UNUSED147', 'val' => 147, 'name' => "unused147", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        148 => ['op' => 'JSOP_UNUSED148', 'val' => 148, 'name' => "unused148", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        149 => ['op' => 'JSOP_BACKPATCH', 'val' => 149, 'name' => "backpatch", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 0, 'format' => ['JOF_JUMP']],
        150 => ['op' => 'JSOP_UNUSED150', 'val' => 150, 'name' => "unused150", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        151 => ['op' => 'JSOP_THROWING', 'val' => 151, 'name' => "throwing", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 0, 'format' => ['JOF_BYTE']],
        152 => ['op' => 'JSOP_SETRVAL', 'val' => 152, 'name' => "setrval", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 0, 'format' => ['JOF_BYTE']],
        153 => ['op' => 'JSOP_RETRVAL', 'val' => 153, 'name' => "retrval", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        154 => ['op' => 'JSOP_GETGNAME', 'val' => 154, 'name' => "getgname", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_TYPESET', 'JOF_GNAME']],
        155 => ['op' => 'JSOP_SETGNAME', 'val' => 155, 'name' => "setgname", 'image' => NULL, 'len' => 5, 'use' => 2, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_SET', 'JOF_DETECTING', 'JOF_GNAME']],
        156 => ['op' => 'JSOP_UNUSED156', 'val' => 156, 'name' => "unused156", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        157 => ['op' => 'JSOP_UNUSED157', 'val' => 157, 'name' => "unused157", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        158 => ['op' => 'JSOP_UNUSED158', 'val' => 158, 'name' => "unused158", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        159 => ['op' => 'JSOP_UNUSED159', 'val' => 159, 'name' => "unused159", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        160 => ['op' => 'JSOP_REGEXP', 'val' => 160, 'name' => "regexp", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_REGEXP']],
        161 => ['op' => 'JSOP_UNUSED161', 'val' => 161, 'name' => "unused161", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        162 => ['op' => 'JSOP_UNUSED162', 'val' => 162, 'name' => "unused162", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        163 => ['op' => 'JSOP_UNUSED163', 'val' => 163, 'name' => "unused163", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        164 => ['op' => 'JSOP_UNUSED164', 'val' => 164, 'name' => "unused164", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        165 => ['op' => 'JSOP_UNUSED165', 'val' => 165, 'name' => "unused165", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        166 => ['op' => 'JSOP_UNUSED166', 'val' => 166, 'name' => "unused166", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        167 => ['op' => 'JSOP_UNUSED167', 'val' => 167, 'name' => "unused167", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        168 => ['op' => 'JSOP_UNUSED168', 'val' => 168, 'name' => "unused168", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        169 => ['op' => 'JSOP_UNUSED169', 'val' => 169, 'name' => "unused169", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        170 => ['op' => 'JSOP_UNUSED170', 'val' => 170, 'name' => "unused170", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        171 => ['op' => 'JSOP_UNUSED171', 'val' => 171, 'name' => "unused171", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        172 => ['op' => 'JSOP_UNUSED172', 'val' => 172, 'name' => "unused172", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        173 => ['op' => 'JSOP_UNUSED173', 'val' => 173, 'name' => "unused173", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        174 => ['op' => 'JSOP_UNUSED174', 'val' => 174, 'name' => "unused174", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        175 => ['op' => 'JSOP_UNUSED175', 'val' => 175, 'name' => "unused175", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        176 => ['op' => 'JSOP_UNUSED176', 'val' => 176, 'name' => "unused176", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        177 => ['op' => 'JSOP_UNUSED177', 'val' => 177, 'name' => "unused177", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        178 => ['op' => 'JSOP_UNUSED178', 'val' => 178, 'name' => "unused178", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        179 => ['op' => 'JSOP_UNUSED179', 'val' => 179, 'name' => "unused179", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        180 => ['op' => 'JSOP_UNUSED180', 'val' => 180, 'name' => "unused180", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        181 => ['op' => 'JSOP_UNUSED181', 'val' => 181, 'name' => "unused181", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        182 => ['op' => 'JSOP_UNUSED182', 'val' => 182, 'name' => "unused182", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        183 => ['op' => 'JSOP_UNUSED183', 'val' => 183, 'name' => "unused183", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        184 => ['op' => 'JSOP_CALLPROP', 'val' => 184, 'name' => "callprop", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP', 'JOF_TYPESET', 'JOF_TMPSLOT3']],
        185 => ['op' => 'JSOP_UNUSED185', 'val' => 185, 'name' => "unused185", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        186 => ['op' => 'JSOP_UNUSED186', 'val' => 186, 'name' => "unused186", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        187 => ['op' => 'JSOP_UNUSED187', 'val' => 187, 'name' => "unused187", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        188 => ['op' => 'JSOP_UINT24', 'val' => 188, 'name' => "uint24", 'image' => NULL, 'len' => 4, 'use' => 0, 'def' => 1, 'format' => ['JOF_UINT24']],
        189 => ['op' => 'JSOP_UNUSED189', 'val' => 189, 'name' => "unused189", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        190 => ['op' => 'JSOP_UNUSED190', 'val' => 190, 'name' => "unused190", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        191 => ['op' => 'JSOP_UNUSED191', 'val' => 191, 'name' => "unused191", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        192 => ['op' => 'JSOP_UNUSED192', 'val' => 192, 'name' => "unused192", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        193 => ['op' => 'JSOP_CALLELEM', 'val' => 193, 'name' => "callelem", 'image' => NULL, 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_ELEM', 'JOF_TYPESET', 'JOF_LEFTASSOC']],
        194 => ['op' => 'JSOP_MUTATEPROTO', 'val' => 194, 'name' => "mutateproto", 'image' => NULL, 'len' => 1, 'use' => 2, 'def' => 1, 'format' => ['JOF_BYTE']],
        195 => ['op' => 'JSOP_GETXPROP', 'val' => 195, 'name' => "getxprop", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP', 'JOF_TYPESET']],
        196 => ['op' => 'JSOP_UNUSED196', 'val' => 196, 'name' => "unused196", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        197 => ['op' => 'JSOP_TYPEOFEXPR', 'val' => 197, 'name' => "typeofexpr", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_DETECTING']],
        198 => ['op' => 'JSOP_PUSHBLOCKSCOPE', 'val' => 198, 'name' => "pushblockscope", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 0, 'format' => ['JOF_OBJECT']],
        199 => ['op' => 'JSOP_POPBLOCKSCOPE', 'val' => 199, 'name' => "popblockscope", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        200 => ['op' => 'JSOP_DEBUGLEAVEBLOCK', 'val' => 200, 'name' => "debugleaveblock", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        201 => ['op' => 'JSOP_UNUSED201', 'val' => 201, 'name' => "unused201", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        202 => ['op' => 'JSOP_GENERATOR', 'val' => 202, 'name' => "generator", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        203 => ['op' => 'JSOP_YIELD', 'val' => 203, 'name' => "yield", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE']],
        204 => ['op' => 'JSOP_ARRAYPUSH', 'val' => 204, 'name' => "arraypush", 'image' => NULL, 'len' => 1, 'use' => 2, 'def' => 0, 'format' => ['JOF_BYTE']],
        205 => ['op' => 'JSOP_UNUSED205', 'val' => 205, 'name' => "unused205", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        206 => ['op' => 'JSOP_UNUSED206', 'val' => 206, 'name' => "unused206", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        207 => ['op' => 'JSOP_UNUSED207', 'val' => 207, 'name' => "unused207", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        208 => ['op' => 'JSOP_UNUSED208', 'val' => 208, 'name' => "unused208", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        209 => ['op' => 'JSOP_UNUSED209', 'val' => 209, 'name' => "unused209", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        210 => ['op' => 'JSOP_UNUSED210', 'val' => 210, 'name' => "unused210", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        211 => ['op' => 'JSOP_UNUSED211', 'val' => 211, 'name' => "unused211", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        212 => ['op' => 'JSOP_UNUSED212', 'val' => 212, 'name' => "unused212", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        213 => ['op' => 'JSOP_UNUSED213', 'val' => 213, 'name' => "unused213", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        214 => ['op' => 'JSOP_BINDGNAME', 'val' => 214, 'name' => "bindgname", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_NAME', 'JOF_SET', 'JOF_GNAME']],
        215 => ['op' => 'JSOP_INT8', 'val' => 215, 'name' => "int8", 'image' => NULL, 'len' => 2, 'use' => 0, 'def' => 1, 'format' => ['JOF_INT8']],
        216 => ['op' => 'JSOP_INT32', 'val' => 216, 'name' => "int32", 'image' => NULL, 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_INT32']],
        217 => ['op' => 'JSOP_LENGTH', 'val' => 217, 'name' => "length", 'image' => NULL, 'len' => 5, 'use' => 1, 'def' => 1, 'format' => ['JOF_ATOM', 'JOF_PROP', 'JOF_TYPESET', 'JOF_TMPSLOT3']],
        218 => ['op' => 'JSOP_HOLE', 'val' => 218, 'name' => "hole", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE']],
        219 => ['op' => 'JSOP_UNUSED219', 'val' => 219, 'name' => "unused219", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        220 => ['op' => 'JSOP_UNUSED220', 'val' => 220, 'name' => "unused220", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        221 => ['op' => 'JSOP_UNUSED221', 'val' => 221, 'name' => "unused221", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        222 => ['op' => 'JSOP_UNUSED222', 'val' => 222, 'name' => "unused222", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        223 => ['op' => 'JSOP_UNUSED223', 'val' => 223, 'name' => "unused223", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 0, 'format' => ['JOF_BYTE']],
        224 => ['op' => 'JSOP_REST', 'val' => 224, 'name' => "rest", 'image' => NULL, 'len' => 1, 'use' => 0, 'def' => 1, 'format' => ['JOF_BYTE', 'JOF_TYPESET']],
        225 => ['op' => 'JSOP_TOID', 'val' => 225, 'name' => "toid", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE']],
        226 => ['op' => 'JSOP_IMPLICITTHIS', 'val' => 226, 'name' => "implicitthis", 'image' => "", 'len' => 5, 'use' => 0, 'def' => 1, 'format' => ['JOF_ATOM']],
        227 => ['op' => 'JSOP_LOOPENTRY', 'val' => 227, 'name' => "loopentry", 'image' => NULL, 'len' => 2, 'use' => 0, 'def' => 0, 'format' => ['JOF_UINT8']],
        228 => ['op' => 'JSOP_TOSTRING', 'val' => 228, 'name' => "tostring", 'image' => NULL, 'len' => 1, 'use' => 1, 'def' => 1, 'format' => ['JOF_BYTE']],
    ];
}


================================================
FILE: src/Context.php
================================================
<?php

/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/1
 * Time: 下午3:25
 */
namespace Irelance\Mozjs34;

use Irelance\Mozjs34\Helper\Operation;
use Irelance\Mozjs34\Helper\Reveal;
use Irelance\Mozjs34\Helper\Stack;

class Context
{
    use Reveal;
    use Operation;

    public $index = null;
    public $decompile = null;
    protected $isDebug = false;

    protected $content = '';
    protected $stack = [];

    protected $argvs = [];
    protected $summaries = [];
    protected $operations = [];
    protected $nodes = [];
    protected $atoms = [];
    protected $consts = [];
    protected $objects = [];
    protected $regexps = [];
    protected $tryNotes = [];
    protected $scopeNotes = [];
    protected $hasLazyScript;

    public function addArgv($value)
    {
        $this->argvs[] = $value;
    }

    public function addSummary($key, $value)
    {
        if (isset($this->summaries[$key])) {
            return false;
        }
        $this->summaries[$key] = $value;
        return true;
    }

    public function addOperation($parserIndex, array $operation)
    {
        $this->operations[$parserIndex] = $operation;
    }

    public function addNode($node)
    {
        $this->nodes[] = $node;
    }

    public function addAtom($atom)
    {
        $this->atoms[] = $atom;
    }

    public function addConst($const)
    {
        $this->consts[] = $const;
    }

    public function addObject($classKind, array $extra)
    {
        $this->objects[] = array_merge($extra, ['classKind' => $classKind]);
    }

    public function addRegexp($source, $flagsword)
    {
        $this->regexps[] = [
            'source' => $source,
            'flagsword' => $flagsword,
        ];
    }

    public function addTryNote($kind, $stackDepth, $start, $length)
    {
        $this->tryNotes[] = ['kind' => $kind, 'stackDepth' => $stackDepth, 'start' => $start, 'length' => $length];
    }

    public function addScopeNote($index, $start, $length, $parent)
    {
        $this->scopeNotes[$index] = ['parent' => $parent, 'start' => $start, 'length' => $length];
    }

    public function addHasLazyScript($packedFields)
    {
        $this->hasLazyScript = $packedFields;
    }

    public function getSummary($key)
    {
        return $this->summaries[$key];
    }

    /**
     * @param $stack Stack|array
     */
    public function pushStack($stack)
    {
        if (is_array($stack)) {
            $stack = new Stack($stack);
        }
        array_push($this->stack, $stack);
    }

    /**
     * @return Stack
     */
    public function popStack()
    {
        return array_pop($this->stack);
    }

    protected $storageScript = [];

    public function writeScript($parserIndex, $string, $offset = 0)
    {
        $this->storageScript[$parserIndex * 2 + $offset] = ['value' => $string];
    }

    public function appendScript($parserIndex, $string, $offset = 0)
    {
        if (!isset($this->storageScript[$parserIndex * 2 + $offset])) {
            $this->writeScript($parserIndex, $string, $offset);
            return;
        }
        $this->storageScript[$parserIndex * 2 + $offset]['value'] .= $string;
    }

    public function getScript($parserIndex, $offset = 0)
    {
        if (!isset($this->storageScript[$parserIndex * 2 + $offset])) {
            return ['value' => ''];
        }
        return $this->storageScript[$parserIndex * 2 + $offset];
    }

    public function dropScript($parserIndex, $offset = 0)
    {
        if (isset($this->storageScript[$parserIndex * 2 + $offset])) {
            unset($this->storageScript[$parserIndex * 2 + $offset]);
        }
    }
}


================================================
FILE: src/Decompile.php
================================================
<?php

/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/9/20
 * Time: 上午8:04
 *
 * js/src/jsscript.h
 * js/src/vm/Xdr.h
 */

namespace Irelance\Mozjs34;

use Irelance\Mozjs34\Helper\Stack;

class Decompile
{
    use Xdr\Common;
    use Xdr\Script;
    use Xdr\Atom;
    use Xdr\ObjectXdr;
    use Xdr\Scope;
    use Xdr\Operation;

    public $isDebug = false;
    private $fp;
    protected $parseIndex = 0;

    protected $buildId = '';
    protected $contexts = [];

    public $bytecodes = [];
    public $bytecodeLength = 0;

    public function __construct($filename)
    {
        $this->fp = fopen($filename, 'rb');
        $this->init();
    }

    public function __destruct()
    {
        fclose($this->fp);
    }

    public function init()
    {
        $i = 0;
        while (!feof($this->fp)) {
            $c = fgetc($this->fp);
            $this->bytecodes[$i] = ord($c);
            $i++;
        }
        $this->bytecodeLength = count($this->bytecodes);
    }

    protected function parserVersion()
    {
        $this->parseIndex = 0;
        $bytecodeVer = $this->todec();
        return $bytecodeVer;
    }

    public function run()
    {
        $this->parserVersion();
        $this->XDRScript();
    }

    public function runResult()
    {
        echo '----------------ByteCode---------------', CLIENT_EOL;
        echo 'file size :', $this->bytecodeLength, CLIENT_EOL;
        echo 'parse size :', 1 + $this->parseIndex, CLIENT_EOL;
        echo '---------------------------------------', CLIENT_EOL;
    }

    public function getContexts()
    {
        return $this->contexts;
    }

    protected $localVariable = [];

    public function setLocalVariable($index, $value)
    {
        $this->localVariable[$index] = $value;
    }

    public function getLocalVariable($index)
    {
        if (!isset($this->localVariable[$index])) {
            return new Stack(['parserIndex' => 0, 'type' => 'undefined', 'value' => 'undefined']);
        }
        return $this->localVariable[$index];
    }

    protected $aliasedVariable = [];

    public function setAliasedVariable($hops, $slot, $value)
    {
        if (!isset($this->aliasedVariable[$hops])) {
            $this->aliasedVariable[$hops] = [];
        }
        $this->aliasedVariable[$hops][$slot] = $value;
    }

    public function getAliasedVariable($hops, $slot)
    {
        if (!isset($this->aliasedVariable[$hops][$slot])) {
            return new Stack(['parserIndex' => 0, 'type' => 'undefined', 'value' => 'undefined']);
        }
        return $this->aliasedVariable[$hops][$slot];
    }

    protected $globalVariable = [];

    public function setGlobalVariable($key, $value)
    {
        $this->globalVariable[$key] = $value;
    }

    public function getGlobalVariable($key)
    {
        if (!isset($this->localVariable[$key])) {
            return new Stack(['parserIndex' => 0, 'type' => 'undefined', 'name' => $key, 'value' => $key]);
        }
        return $this->globalVariable[$key];
    }
}


================================================
FILE: src/Helper/Operation.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/11
 * Time: 上午11:06
 */

namespace Irelance\Mozjs34\Helper;


use Irelance\Mozjs34\Constant;

/**
 * @method Stack popStack()
 */
trait Operation
{
    protected $logicStacks = [];

    protected function gotoNextOperation($nextOperation)
    {
        while (isset($nextOperation['params']['offset'])) {
            $goto = $nextOperation['parserIndex'] + $nextOperation['params']['offset'];
            if (!isset($this->operations[$goto])) {
                return false;
            }
            $nextOperation = $this->operations[$goto];
        }
        return $nextOperation;
    }

    public function getNextOperation($operation)
    {
        $nextIndex = $operation['parserIndex'] + $operation['length'];
        if (!isset($this->operations[$nextIndex])) {
            return false;
        }
        return $this->operations[$nextIndex];
    }

    public function revealOperations($start, $end, $conditons = [], $isCover = true)
    {
        $operationKeys = array_keys($this->operations);
        $operationKeysFlip = array_flip($operationKeys);
        $start = $operationKeysFlip[$start];
        $end = $operationKeysFlip[$end];
        for ($i = $start; $i < $end; $i++) {
            $operation = $this->operations[$operationKeys[$i]];
            if (!$operation['isCover']) {
                if ($this->isDebug) {
                    echo '[', $operationKeys[$i], ']', $operation['name'], json_encode($operation['params']), ' pop: ', $operation['pop'], ' push: ', $operation['push'], ' byte: ', $operation['length'], CLIENT_EOL;
                }
                $this->revealOperation($operation, $conditons);
                $this->operations[$operationKeys[$i]]['isCover'] = $isCover;
            }
        }
    }

    protected function hasOperation($start, $end, $name)
    {
        $operationKeys = array_keys($this->operations);
        $operationKeysFlip = array_flip($operationKeys);
        $start = $operationKeysFlip[$start];
        $end = $operationKeysFlip[$end];
        for ($i = $start + 1; $i < $end; $i++) {
            $operation = $this->operations[$operationKeys[$i]];
            if ($operation['name'] == $name) {
                return true;
            }
        }
        return false;
    }

    protected function findFirstOperation($name, $start = null, $end = null)
    {
        if (is_string($name)) {
            $name = [$name];
        }
        $operationKeys = array_keys($this->operations);
        $operationKeysFlip = array_flip($operationKeys);
        $start = is_null($start) ? 0 : $operationKeysFlip[$start];
        $end = is_null($end) ? count($operationKeys) : $operationKeysFlip[$end];
        for ($i = $start; $i < $end; $i++) {
            $operation = $this->operations[$operationKeys[$i]];
            if (in_array($operation['name'], $name)) {
                return $operation;
            }
        }
        return false;
    }

    public function revealOperation($operation, $conditons = [])
    {
        switch ($operation['name']) {
            case 'JSOP_RETRVAL':
            case 'JSOP_ENDINIT':
            case 'JSOP_NOP':
                break;
            case 'JSOP_RETURN':
                $value = $this->getLogicValue($operation, $this->popStack());
                $this->writeScript($operation['parserIndex'], 'return ' . $value . ';');
                break;
            //change stack
            case 'JSOP_POP':
            case 'JSOP_SETRVAL':
                $rVal = $this->popStack();
                if ($rVal && $script = $rVal->getScript()) {
                    $this->writeScript($operation['parserIndex'], $script . ';');
                }
                break;
            case 'JSOP_POPN':
                $n = $operation['params']['n'];
                for ($i = 0; $i < $n; $i++) {
                    $this->popStack();
                }
                break;
            case 'JSOP_DUP':
                $val = $this->popStack();
                $this->pushStack($val);
                $this->pushStack($val);
                break;
            case 'JSOP_DUP2':
                $val1 = $this->popStack();
                $val2 = $this->popStack();
                $this->pushStack($val2);
                $this->pushStack($val1);
                $this->pushStack($val2);
                $this->pushStack($val1);
                break;
            case 'JSOP_DUPAT':
                $number = $operation['params']['n'];
                $temp = [];
                for ($i = 0; $i < $number; $i++) {
                    $temp[$i] = $this->popStack();
                }
                for ($i = $number - 1; $i >= 0; $i--) {
                    $this->pushStack($temp[$i]);
                }
                $this->pushStack($temp[$number - 1]);
                break;
            case 'JSOP_PICK':
                $number = $operation['params']['n'];
                $temp = [];
                for ($i = 0; $i < $number; $i++) {
                    $temp[$i] = $this->popStack();
                }
                $nTh = $this->popStack();
                for ($i = $number - 1; $i >= 0; $i--) {
                    $this->pushStack($temp[$i]);
                }
                $this->pushStack($nTh);
                break;
            case 'JSOP_SWAP':// v1, v2 => v2, v1
                $val1 = $this->popStack();
                $val2 = $this->popStack();
                $this->pushStack($val1);
                $this->pushStack($val2);
                break;
            //control goto
            case 'JSOP_GOTO':
                if (!empty($conditons)) {
                    if (isset($conditons['type']) && $conditons['type'] == 'switch') {
                        $gotoIndex = $operation['parserIndex'] + $operation['params']['offset'];
                        if ($gotoIndex >= $conditons['defaultIndex']) {
                            $this->writeScript($operation['parserIndex'], 'break;');
                            $this->writeScript($gotoIndex, '}', +1);
                            return;
                        }
                    }
                }
                $this->_getBranchContinue($operation) || $this->_getBranchBreak($operation);
                break;
            //control branch
            case 'JSOP_IFEQ':
                $value = $this->getLogicValue($operation, $this->popStack());
                //storage stack for k=x?a:b
                $stackCopy = serialize($this->stack);
                $this->appendScript($operation['parserIndex'], 'if(' . $value . '){');
                if ($operation['params']['offset'] > 0) {
                    $elseStart = $this->gotoNextOperation($operation);
                    $this->revealOperations($operation['parserIndex'] + $operation['length'], $elseStart['parserIndex']);
                    $gotoOperation = $this->_getBranchGoto($operation);
                    while ($this->_getBranchContinue($gotoOperation) || $this->_getBranchBreak($gotoOperation)) {
                        $gotoOperation = $this->findFirstOperation('JSOP_GOTO', $gotoOperation['parserIndex'] + $gotoOperation['length']);
                        if (!$gotoOperation) {
                            break;
                        }
                    }
                    $hasNextOperation = false;
                    $nextOperationIndex = false;
                    if ($gotoOperation) {
                        $hasNextOperation = $gotoOperation['name'];
                        $nextOperationIndex = $gotoOperation['parserIndex'];
                        if ($elseIfOperation = $this->findFirstOperation(
                            'JSOP_IFEQ',
                            $gotoOperation['parserIndex'],
                            $gotoOperation['parserIndex'] + $gotoOperation['params']['offset']
                        )
                        ) {
                            $hasNextOperation = $elseIfOperation['name'];
                            $nextOperationIndex = $elseIfOperation['parserIndex'];
                        }
                    }
                    switch ($hasNextOperation) {
                        case 'JSOP_IFEQ':
                            $this->writeScript($nextOperationIndex, '} else ');
                            break;
                        case 'JSOP_GOTO':
                            $this->writeScript($nextOperationIndex, '} else {');
                        default:
                            $this->appendScript($operation['parserIndex'] + $operation['params']['offset'], '}', +1);
                            break;
                    }
                    $oldCount = count(unserialize($stackCopy));
                    $newCount = count($this->stack);
                    if ($oldCount != $newCount) {
                        if (($newCount - $oldCount) != 1) {
                            exit("[error] JSOP_IFEQ Unknown Type");
                        }
                        $this->dropScript($nextOperationIndex);
                        $this->dropScript($operation['parserIndex']);
                        $this->dropScript($operation['parserIndex'] + $operation['params']['offset'], +1);
                        if (!$gotoOperation) {
                            exit("[error] JSOP_IFEQ No Goto ");
                        }
                        $setIndex = $gotoOperation['parserIndex'] + $gotoOperation['params']['offset'];
                        $setOperation = $this->operations[$setIndex];
                        switch ($setOperation['name']) {
                            case 'JSOP_SETELEM':
                            case 'JSOP_SETNAME':
                            case 'JSOP_SETCONST':
                            case 'JSOP_SETPROP':
                            case 'JSOP_INITPROP':
                                $endOperation = $this->getNextOperation($setOperation);
                                break;
                            default://todo find all ending operation
                                $endOperation = $this->findFirstOperation(
                                    ['JSOP_SETRVAL', 'JSOP_GOTO', 'JSOP_POP', 'JSOP_RETURN', 'JSOP_IFEQ', 'JSOP_IFNE',
                                    ],
                                    $setIndex
                                );
                                break;
                        }
                        if (!$endOperation) {
                            exit("[error] JSOP_IFEQ Unknown endOperation " . $operation['parserIndex']);
                        }
                        $this->revealOperations($setIndex, $endOperation['parserIndex'], [], false);
                        $left = $this->popStack();
                        $this->stack = unserialize($stackCopy);
                        $this->revealOperations($gotoOperation['parserIndex'] + 5, $endOperation['parserIndex']);
                        $right = $this->popStack();
                        $this->pushStack(['type' => 'script', 'script' => $value . '?' . $left->getScript() . ':' . $right->getScript()]);
                        return;
                    }
                }
                break;
            case 'JSOP_TABLESWITCH':
                //case type is int
                $val = $this->popStack();
                $this->writeScript($operation['parserIndex'], 'switch(' . $val->getValue() . '){');
                $caseCurrent = $operation['params']['low'];
                $contents = [];
                foreach ($operation['params']['offset'] as $offset) {
                    if ($offset) {
                        $contentIndex = $operation['parserIndex'] + $offset;
                        if (!isset($contents[$contentIndex])) {
                            $contents[$contentIndex] = [];
                        }
                        $contents[$contentIndex][] = ['value' => 'case ' . $caseCurrent . ':'];
                    }
                    $caseCurrent++;
                }
                $defaultIndex = $operation['parserIndex'] + $operation['params']['len'];
                $this->_renderSwitch($contents, $defaultIndex);
                break;
            //control branch switch case type is mix
            case 'JSOP_CONDSWITCH':
                $name = $this->popStack();
                $this->writeScript($operation['parserIndex'], 'switch(' . $name->getValue() . '){');
                $this->pushStack(['type' => 'switch', 'value' => []]);
                break;
            case 'JSOP_CASE':
                $val = $this->popStack();
                $switch = $this->popStack();
                $contentIndex = $operation['parserIndex'] + $operation['params']['offset'];
                if (!isset($switch->value[$contentIndex])) {
                    $switch->value[$contentIndex] = [];
                }
                $switch->value[$contentIndex][] = ['value' => 'case ' . $val->getValue() . ':'];
                $this->pushStack($switch);
                break;
            case 'JSOP_DEFAULT':
                $switch = $this->popStack();
                $this->_renderSwitch($switch->value, $operation['parserIndex'] + $operation['params']['offset']);
                break;
            //control loop
            case 'JSOP_IFNE':
                $value = $this->getLogicValue($operation, $this->popStack());
                $this->writeScript($operation['parserIndex'], 'if(' . $value . ')');
                break;
            case 'JSOP_LOOPHEAD':
                $gotoOperation = $this->_getLoopGoto($operation);
                $isDo = !$gotoOperation;
                if ($isDo) {
                    $this->writeScript($operation['parserIndex'], 'do{', -1);
                    $entryOperation = $this->operations[$operation['parserIndex'] + $operation['length']];
                    $ifOperation = $entryOperation;
                    do {
                        $ifOperation = $this->_getLoopLogic($ifOperation);
                    } while ($this->operations[$ifOperation['parserIndex'] + $ifOperation['params']['offset']]['parserIndex'] != $operation['parserIndex']);
                } else {
                    $entryOperation = $this->operations[$gotoOperation['parserIndex'] + $gotoOperation['params']['offset']];
                    $ifOperation = $this->_getLoopLogic($entryOperation);
                }
                $this->revealOperations($entryOperation['parserIndex'], $ifOperation['parserIndex'] + $ifOperation['length']);
                $this->revealOperations($operation['parserIndex'] + $operation['length'], $entryOperation['parserIndex']);
                if ($isDo) {
                    $this->writeScript(
                        $ifOperation['parserIndex'],
                        str_replace('if(', '} while(', $this->getScript($ifOperation['parserIndex'])['value'])
                    );
                } else {
                    $this->writeScript(
                        $operation['parserIndex'],
                        str_replace('if(', 'while(', $this->getScript($ifOperation['parserIndex'])['value']) . '{',
                        -1
                    );
                    $this->writeScript($ifOperation['parserIndex'], '}');
                }
                break;
            case 'JSOP_LOOPENTRY':
                break;
            //For-In Statement
            case 'JSOP_ITER':
                $val = $this->popStack();
                $this->pushStack($val);
                break;
            case 'JSOP_ITERNEXT':
                $this->pushStack(['type' => 'script', 'name' => '_iternext']);
                break;
            case 'JSOP_MOREITER':
                $val = $this->popStack();
                $this->pushStack([]);
                $this->pushStack(['type' => 'script', 'script' => $val->getValue() . ' has _iternext']);
                break;
            case 'JSOP_ENDITER':
                $val = $this->popStack();
                break;
            //math
            case 'JSOP_BITNOT':
            case 'JSOP_NEG':
                $value = $this->getLogicValue($operation, $this->popStack());
                $this->pushStack(['script' => '(' . $operation['image'] . $value . ')', 'type' => 'script']);
                break;
            case 'JSOP_POS':
                break;
            //math
            case 'JSOP_ADD':
            case 'JSOP_SUB':
            case 'JSOP_MUL':
            case 'JSOP_DIV':
            case 'JSOP_MOD':
            case 'JSOP_BITOR':
            case 'JSOP_BITXOR':
            case 'JSOP_BITAND':
            case 'JSOP_RSH':
            case 'JSOP_LSH':
            case 'JSOP_URSH':
                //logic
            case 'JSOP_EQ':
            case 'JSOP_NE':
            case 'JSOP_LT':
            case 'JSOP_LE':
            case 'JSOP_GT':
            case 'JSOP_GE':
            case 'JSOP_STRICTEQ':
            case 'JSOP_STRICTNE':
            case 'JSOP_IN':
                $right = $this->popStack();
                $rVal = $right->getValue();
                $left = $this->popStack();
                $lVal = $left->getValue();
                if ($left->type == 'logic') {
                    $lVal = $this->_combineLogicByParserIndex($left->operation['parserIndex']);
                }
                if ($right->type == 'logic') {
                    $rVal = $this->_combineLogicByParserIndex($right->operation['parserIndex']);
                }
                $this->pushStack(['script' => '(' . $lVal . ' ' . $operation['image'] . ' ' . $rVal . ')', 'type' => 'script']);
                break;
            case 'JSOP_OR':
                $script = $this->popStack();
                $gotoIndex = $operation['parserIndex'] + $operation['params']['offset'];
                $this->logicStacks[$operation['parserIndex']] = ['type' => 'or', 'goto' => $gotoIndex, 'value' => $script->getValue()];
                $this->pushStack(['type' => 'logic', 'operation' => $operation]);
                break;
            case 'JSOP_AND':
                $script = $this->popStack();
                $gotoIndex = $operation['parserIndex'] + $operation['params']['offset'];
                $this->logicStacks[$operation['parserIndex']] = ['type' => 'and', 'goto' => $gotoIndex, 'value' => $script->getValue()];
                $this->pushStack(['type' => 'logic', 'operation' => $operation]);
                break;
            case 'JSOP_NOT':
                $script = $this->popStack();
                $this->logicStacks[$operation['parserIndex']] = ['type' => 'not', 'value' => $script->getValue()];
                $this->pushStack(['type' => 'logic', 'operation' => $operation]);
                break;
            //typeof
            case 'JSOP_TYPEOF':
            case 'JSOP_TYPEOFEXPR':
                $name = $this->popStack();
                $this->pushStack(['script' => 'typeof ' . $name->getValue(), 'type' => 'script']);
                break;
            //instanceof
            case 'JSOP_INSTANCEOF':
                $rVal = $this->popStack();
                $lVal = $this->popStack();
                $this->pushStack(['script' => $lVal->getValue() . ' instanceof ' . $rVal->getValue(), 'type' => 'script']);
                break;
            //Function
            case 'JSOP_NEW':
            case 'JSOP_FUNAPPLY'://apply
            case 'JSOP_FUNCALL'://call
            case 'JSOP_EVAL'://eval
            case 'JSOP_CALL':
                $_argc = $operation['params']['argc'];
                $_argv = [];
                for ($i = 0; $i < $_argc; $i++) {
                    $_argv[] = $this->popStack();
                }
                $_this = $this->popStack();
                $_callee = $this->popStack();
                $write = '';
                if (!empty($this->logicStacks)) {
                    $write .= $this->_combineLogicByGotoIndex($operation['parserIndex'] + $operation['length']);
                }
                if ($operation['name'] == 'JSOP_NEW') {
                    $write = 'new ';
                }
                $write .= $_callee->name ? $_callee->name : ('(' . $_callee->getScript() . ')');
                $write .= '(';
                if ($_argc) {
                    for ($i = $_argc - 1; $i >= 0; $i--) {
                        //$argv = $_argv[$i]->getScript() ? $_argv[$i]->getScript() : $_argv[$i]->name;//todo
                        $argv = $_argv[$i]->getValue();
                        $write .= $argv . ',';
                    }
                    $write = substr($write, 0, strlen($write) - 1);
                }
                $write .= ')';
                $this->pushStack(['type' => 'script', 'script' => $write]);
                break;
            //Object
            case 'JSOP_NEWINIT':
                $this->pushStack(['value' => [], 'type' => 'object']);
                break;
            case 'JSOP_INITPROP':
                $name = $this->atoms[$operation['params']['nameIndex']];
                $val = $this->popStack();
                $array = $this->popStack();
                $array->value[$name] = $val;
                $this->pushStack($array);
                break;
            case 'JSOP_DELPROP':
                $obj = $this->popStack();
                $this->pushStack(['type' => 'script', 'script' => 'delete ' . $obj->getValue() . '.' . $this->atoms[$operation['params']['nameIndex']]]);
                break;
            case 'JSOP_SETPROP':
                $value = $this->getLogicValue($operation, $this->popStack());
                $name = $this->popStack();
                $this->pushStack(['type' => 'script', 'script' => $name->getValue() . '.' . $this->atoms[$operation['params']['nameIndex']] . '=' . $value]);
                break;
            case 'JSOP_GETPROP':
            case 'JSOP_CALLPROP':
                $obj = $this->popStack();
                $this->pushStack(['name' => $obj->getValue() . '.' . $this->atoms[$operation['params']['nameIndex']]]);
                break;
            case 'JSOP_INITELEM':
            case 'JSOP_INITELEM_INC':
                $val = $this->popStack();
                $name = $this->popStack();
                $array = $this->popStack();
                $array->value[$name->getValue()] = $val;
                $this->pushStack($array);
                break;
            case 'JSOP_DELELEM':
                $propval = $this->popStack();
                $obj = $this->popStack();
                $this->pushStack(['type' => 'script', 'script' => 'delete ' . $obj->getValue() . '[' . $propval->getValue() . ']']);
                break;
            case 'JSOP_SETELEM':
                $value = $this->getLogicValue($operation, $this->popStack());
                $propval = $this->popStack();
                $obj = $this->popStack();
                $this->pushStack(['type' => 'script', 'script' => $obj->getValue() . '[' . $propval->getValue() . ']=' . $value]);
                break;
            case 'JSOP_GETELEM':
            case 'JSOP_CALLELEM':
                $propval = $this->popStack();
                $obj = $this->popStack();
                $this->pushStack(['name' => $obj->getValue() . '[' . $propval->getValue() . ']']);
                break;
            //Array
            case 'JSOP_NEWARRAY':
                $this->pushStack(['value' => [], 'type' => 'array']);
                break;
            case 'JSOP_INITELEM_ARRAY':
                $val = $this->popStack();
                $array = $this->popStack();
                $array->value[] = $val;
                $this->pushStack($array);
                break;
            case 'JSOP_LENGTH':
                $name = $this->popStack();
                $this->pushStack(['type' => 'script', 'script' => $name->getValue() . '.length']);
                break;
            //压入变量
            case 'JSOP_NAME':
            case 'JSOP_BINDNAME':
            case 'JSOP_IMPLICITTHIS':
                $this->pushStack(['name' => $this->atoms[$operation['params']['nameIndex']]]);
                break;
            //定义变量
            case 'JSOP_DEFVAR':
                $this->writeScript($operation['parserIndex'], 'var ' . $this->atoms[$operation['params']['nameIndex']] . ';');
                break;
            case 'JSOP_DEFCONST':
                $this->writeScript($operation['parserIndex'], 'const ' . $this->atoms[$operation['params']['nameIndex']] . ';');
                break;
            case 'JSOP_DEFFUN':
                $object = $this->objects[$operation['params']['funcIndex']];
                $this->writeScript($operation['parserIndex'], 'function ' . $object['name'] . '( __ARGV_' . $object['contextIndex'] . '__ ){ __FUNC_' . $object['contextIndex'] . '__ }');
                break;
            //定义常量 ['isJson'=>false,'value'=>'xxxx']
            case 'JSOP_TRUE':
                $this->pushStack(['value' => 'true', 'type' => 'boolean']);
                break;
            case 'JSOP_FALSE':
                $this->pushStack(['value' => 'false', 'type' => 'boolean']);
                break;
            case 'JSOP_NULL':
                $this->pushStack(['value' => 'null', 'type' => 'null']);
                break;
            case 'JSOP_VOID':
                $val = $this->popStack();
            case 'JSOP_UNDEFINED':
                $this->pushStack(['value' => 'undefined', 'type' => 'undefined']);
                break;
            case 'JSOP_ZERO':
                $this->pushStack(['value' => 0, 'type' => 'number']);
                break;
            case 'JSOP_ONE':
                $this->pushStack(['value' => 1, 'type' => 'number']);
                break;
            case 'JSOP_INT8':
            case 'JSOP_UINT16':
            case 'JSOP_UINT24':
            case 'JSOP_INT32':
                $this->pushStack(['value' => $operation['params']['val'], 'type' => 'number']);
                break;
            case 'JSOP_DOUBLE':
                $this->pushStack(['value' => $this->consts[$operation['params']['constIndex']]['value'], 'type' => 'number']);
                break;
            case 'JSOP_STRING':
                $this->pushStack(['value' => $this->atoms[$operation['params']['atomIndex']], 'type' => 'string']);
                break;
            case 'JSOP_REGEXP':
                $this->pushStack(['value' => '/' . $this->regexps[$operation['params']['regexpIndex']]['source'] . '/', 'type' => 'regexp']);
                break;
            case 'JSOP_OBJECT'://todo
                $object = $this->objects[$operation['params']['objectIndex']];
                $value = [];
                foreach ($object['initialized'] as $k => $v) {
                    $type = 'undefined';
                    switch ($v['type']) {
                        case 'SCRIPT_INT':
                        case 'SCRIPT_DOUBLE':
                            $type = 'number';
                            break;
                        case 'SCRIPT_ATOM':
                            $type = 'string';
                            break;
                        case 'SCRIPT_TRUE':
                        case 'SCRIPT_FALSE':
                            $type = 'boolean';
                            break;
                        case 'SCRIPT_NULL':
                            $type = 'null';
                            break;
                        case 'SCRIPT_OBJECT'://todo maybe function
                            $type = 'object';
                            break;
                        //case 'SCRIPT_VOID':
                        //case 'SCRIPT_HOLE':
                    }
                    $value[$k] = new Stack(['value' => $v['value'], 'type' => $type]);
                }
                $this->pushStack(['value' => $value, 'type' => 1 == $object['isArray'] ? 'array' : 'object']);
                break;
            case 'JSOP_LAMBDA_ARROW':
                $_this = $this->popStack();
                $object = $this->objects[$operation['params']['funcIndex']];
                $this->pushStack(['value' => $object['contextIndex'], 'type' => 'function']);
                break;
            case 'JSOP_LAMBDA':
                $object = $this->objects[$operation['params']['funcIndex']];
                $this->pushStack(['value' => $object['contextIndex'], 'type' => 'function']);
                break;
            //赋值
            case 'JSOP_SETNAME':
                $value = $this->getLogicValue($operation, $this->popStack());
                $name = $this->popStack();
                $name->value = $value;
                $name->script = $name->getValue() . ' = ' . $value;
                $name->type = 'script';
                $this->pushStack($name);
                break;
            case 'JSOP_SETCONST':
                $value = $this->getLogicValue($operation, $this->popStack());
                $name = $this->atoms[$operation['params']['nameIndex']];
                $this->pushStack([
                    'type' => 'script',
                    'name' => $name->value,
                    'value' => $value,
                    'script' => $name->value . ' = ' . $value,
                ]);
                break;
            //delete
            case 'JSOP_DELNAME':
                $this->pushStack(['type' => 'script', 'script' => 'delete ' . $this->atoms[$operation['params']['nameIndex']]]);
                break;
            //todo list
            //Other
            case 'JSOP_TOSTRING':
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_LINENO':
                break;
            //With Statement
            case 'JSOP_ENTERWITH':
                $val = $this->popStack();
                break;
            case 'JSOP_LEAVEWITH':
                break;
            //Arguments
            case 'JSOP_CALLEE':
                $this->pushStack([]);
                break;
            case 'JSOP_ARGUMENTS':
                $this->pushStack(['name' => 'arguments']);
                break;
            case 'JSOP_REST':
                $this->pushStack(['name' => 'rest']);
                break;
            case 'JSOP_SETARG':
                $val = $this->popStack();
                $this->pushStack([
                    'type' => 'script',
                    'name' => $this->argvs[$operation['params']['argno']],
                    'script' => $this->argvs[$operation['params']['argno']] . ' = ' . $val->getValue(),
                ]);
                break;
            case 'JSOP_GETARG':
                $this->pushStack(['name' => $this->argvs[$operation['params']['argno']]]);
                break;
            //Array
            case 'JSOP_NEWARRAY_COPYONWRITE':
                $this->pushStack([]);
                break;
            case 'JSOP_HOLE':
                $this->pushStack([]);
                break;
            case 'JSOP_ARRAYPUSH':
                $val = $this->popStack();
                $array = $this->popStack();
                break;
            //Object
            case 'JSOP_TOID':
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_MUTATEPROTO':
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_GETXPROP':
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_CALLSITEOBJ':
                $this->pushStack([]);
                break;
            case 'JSOP_INITPROP_GETTER':
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_INITPROP_SETTER':
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_INITELEM_GETTER':
                $val = $this->popStack();
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_INITELEM_SETTER':
                $val = $this->popStack();
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_NEWOBJECT':
                $this->pushStack(['value' => [], 'type' => 'object']);
                break;
            //This
            case 'JSOP_THIS':
                $this->pushStack(['name' => 'this']);
                break;
            //Function
            case 'JSOP_SETCALL':
                break;
            case 'JSOP_RUNONCE':
                break;
            case 'JSOP_SPREADCALL':
                $val = $this->popStack();
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_SPREADNEW':
                $val = $this->popStack();
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            case 'JSOP_SPREADEVAL':
                $val = $this->popStack();
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;
            //Free Variables
            case 'JSOP_BINDGNAME':
            case 'JSOP_GETGNAME'://todo check if this different from local, for just access variable name
                $key = $this->atoms[$operation['params']['nameIndex']];
                $this->pushStack($this->decompile->getGlobalVariable($key));
                break;
            case 'JSOP_SETGNAME':
                $value = $this->popStack();
                $bind = $this->popStack();
                $key = $this->atoms[$operation['params']['nameIndex']];
                $globalVar = [
                    'type' => 'script',
                    'name' => $key,
                    'value' => $value,
                    'script' => $key . '=' . $value->getValue(),
                ];
                $this->decompile->setLocalVariable($key, $globalVar);
                $this->pushStack($globalVar);
                break;
            //Local Variables
            case 'JSOP_GETLOCAL'://todo
                $localno = $operation['params']['localno'];
                $this->pushStack($this->decompile->getLocalVariable($localno));
                break;
            case 'JSOP_SETLOCAL'://todo
                $raw = $this->popStack();
                $value = $raw->name ?: $this->getLogicValue($operation, $raw);
                $localno = $operation['params']['localno'];
                $name = '_local' . $localno;
                $localVar = [
                    'type' => 'script',
                    'name' => $name,
                    'value' => $value,
                    'script' => $name . '=' . $value,
                ];
                $this->decompile->setLocalVariable($localno, $localVar);
                $this->pushStack($localVar);
                break;
            //Generator
            case 'JSOP_GENERATOR':
                break;
            case 'JSOP_YIELD':
                $val = $this->popStack();
                $this->pushStack(['type' => 'script', 'value' => 'yield ' . $val->getValue()]);
                break;
            //Aliased Variables
            case 'JSOP_GETALIASEDVAR'://todo
                $aliasedVar = $this->decompile->getAliasedVariable($operation['params']['hops'], $operation['params']['slot']);
                $this->pushStack($aliasedVar);
                break;
            case 'JSOP_SETALIASEDVAR'://todo
                $value = $this->getLogicValue($operation, $this->popStack());
                $aliasedVar = ['type' => 'aliasedVar', 'name' => '_aliased' . rand(1000, 9999)];
                $this->decompile->setAliasedVariable($operation['params']['hops'], $operation['params']['slot'], $aliasedVar);
                $this->pushStack(['type' => 'script', 'name' => $aliasedVar['name'], 'script' => $aliasedVar['name'] . '=' . $value]);
                break;
            //Exception Handling
            case 'JSOP_TRY':
                $this->writeScript($operation['parserIndex'], 'try{');
                break;
            case 'JSOP_THROW':
                $val = $this->popStack();
                $this->writeScript($operation['parserIndex'], 'throw ' . $val->getValue());
                break;
            case 'JSOP_GOSUB':
                break;
            case 'JSOP_EXCEPTION':
                $exception = ['type' => 'exception', 'value' => '@error'];
                $this->writeScript($operation['parserIndex'], '}catch(' . $exception['value'] . '){');
                $this->pushStack($exception);
                break;
            case 'JSOP_DEBUGLEAVEBLOCK':
                $this->writeScript($operation['parserIndex'], '}
        ');
                break;
            case 'JSOP_FINALLY':
                $this->writeScript($operation['parserIndex'], 'finally{
        ');
                $this->pushStack([]);
                $this->pushStack([]);
                break;
            case 'JSOP_RETSUB':
                $this->writeScript($operation['parserIndex'], '}');
                $val = $this->popStack();
                $val = $this->popStack();
                break;
            //todo
            case 'JSOP_DEBUGGER':
                break;
            case 'JSOP_THROWING':
                $val = $this->popStack();
                break;
            //Block-local Scope
            case 'JSOP_POPBLOCKSCOPE':
                break;
            case 'JSOP_PUSHBLOCKSCOPE':
                break;
            //Jumps
            case 'JSOP_BACKPATCH':
                break;
            case 'JSOP_LABEL':
                break;
            //Intrinsics
            case 'JSOP_BINDINTRINSIC':
                $this->pushStack([]);
                break;
            case 'JSOP_GETINTRINSIC':
                $this->pushStack([]);
                break;
            case 'JSOP_SETINTRINSIC':
                $val = $this->popStack();
                $val = $this->popStack();
                $this->pushStack([]);
                break;

        }
    }

    protected function _renderSwitch($contents, $defaultIndex)
    {
        $contentEndings = array_keys($contents);
        $contentEndings[] = $defaultIndex;
        $i = 1;
        foreach ($contents as $start => $content) {
            $caseWrite = '';
            foreach ($content as $case) {
                $caseWrite .= $case['value'];
            }
            $this->writeScript($start, $caseWrite, -1);
            $this->revealOperations($start, $contentEndings[$i], ['type' => 'switch', 'defaultIndex' => $defaultIndex,]);
            $i++;
        }
        $this->writeScript($defaultIndex, 'default:');
    }

    protected function getLogicValue($operation, Stack $val)
    {
        $value = $val->getValue();
        if (!empty($this->logicStacks)) {
            $value = $this->_combineLogicByGotoIndex($operation['parserIndex'] + $operation['length']) . $value;
        }
        return $value;
    }

    protected function _getLoopGoto($operation)
    {
        $gotoIndex = $operation['parserIndex'] - 5;
        if (!isset($this->operations[$gotoIndex])) {
            return false;
        }
        $gotoOperation = $this->operations[$gotoIndex];
        if ($gotoOperation['name'] !== 'JSOP_GOTO') {
            return false;
        }
        return $gotoOperation;
    }

    protected function _getLoopLogic($entry)
    {
        $if = $entry;
        do {
            $if = $this->findFirstOperation(
                ['JSOP_IFNE', 'JSOP_IFEQ'],
                $if['parserIndex'] + $if['length']
            );
            if (!$if) {
                return false;
            }
        } while ($if['params']['offset'] > 0);
        return $if;
    }

    protected function _getBranchGoto($operation)
    {
        $gotoIndex = $operation['parserIndex'] + $operation['params']['offset'] - 5;
        if (!isset($this->operations[$gotoIndex])) {
            return false;
        }
        $gotoOperation = $this->operations[$gotoIndex];
        if ($gotoOperation['name'] !== 'JSOP_GOTO') {
            return false;
        }
        return $gotoOperation;
    }

    protected function _getBranchBreak($goto)
    {
        if ($goto['params']['offset'] > 0) {
            if ($this->hasOperation($goto['parserIndex'], $goto['parserIndex'] + $goto['params']['offset'], 'JSOP_LOOPENTRY')) {
                $this->writeScript($goto['parserIndex'], 'break;');
                return true;
            }
        }
        return false;
    }

    protected function _getBranchContinue($goto)
    {
        if ($goto['params']['offset'] < 0) {
            $nextOperation = $this->gotoNextOperation($goto);
            if ($nextOperation['name'] == 'JSOP_LOOPENTRY') {
                $this->writeScript($goto['parserIndex'], 'continue;');
                return true;
            }
        }
        return false;
    }

    protected function _combineLogic()
    {
        ksort($this->logicStacks);
        while (count($this->logicStacks) > 1) {
            $this->_combineLogicUnit();
        }
        $result = array_pop($this->logicStacks);
        switch ($result['type']) {
            case 'not':
                $result['value'] = '!(' . $result['value'] . ')';
                break;
            case 'and':
                $result['value'] = $result['value'] . '&&';
                break;
            case 'or':
                $result['value'] = $result['value'] . '||';
                break;
        }
        return $result['value'];
    }

    protected function _getLogicScript($stack)
    {
        $value = '';
        $isNot = $stack['type'] == 'not';
        if ($isNot) {
            $value .= '!(';
        }
        $value .= $stack['value'];
        if ($isNot) {
            $value .= ')';
        }
        switch ($stack['type']) {
            case 'and':
                $value .= ' && ';
                break;
            case 'or':
                $value .= ' || ';
                break;
        }
        return $value;
    }

    protected function _combineLogicUnit()
    {
        $logicStackKeys = array_keys($this->logicStacks);
        $logicStackKeysCount = count($logicStackKeys);
        $tree = ['type' => 'script'];
        for ($i = 0; $i < $logicStackKeysCount; $i++) {
            $logicStack = $this->logicStacks[$logicStackKeys[$i]];
            if (is_null($logicStack['value'])) {
                $preStack = $this->logicStacks[$logicStackKeys[$i - 1]];
                $this->logicStacks[$logicStackKeys[$i]]['value'] = $preStack['type'] == 'not' ? ('!(' . $preStack['value'] . ')') : $preStack['value'];
                unset($this->logicStacks[$logicStackKeys[$i - 1]]);
            } elseif (!isset($logicStackKeys[$i + 1])) {//if last one
                $preStack = $this->logicStacks[$logicStackKeys[$i - 1]];
                $value = $this->_getLogicScript($preStack) . $this->_getLogicScript($logicStack);
                $this->logicStacks[$logicStackKeys[$i - 1]] = ['value' => $value, 'type' => 'script'];
                unset($this->logicStacks[$logicStackKeys[$i]]);
            } elseif (!isset($logicStack['goto'])) {
                continue;
            } elseif ($logicStackKeys[$i + 1] == $logicStack['goto']) {
                $nextLogicStack = $this->logicStacks[$logicStackKeys[$i + 1]];
                $isNot = $nextLogicStack['type'] == 'not' ? '!' : '';
                switch ($logicStack['type']) {
                    case 'and':
                        $tree['value'] = $isNot . '(' . $logicStack['value'] . ' && ' . $nextLogicStack['value'] . ')';
                        break;
                    case 'or':
                        $tree['value'] = $isNot . '(' . $logicStack['value'] . ' || ' . $nextLogicStack['value'] . ')';
                        break;
                    case 'script':
                        $tree['value'] = $logicStack['value'] . $nextLogicStack['value'];
                        break;
                }
                if (isset($nextLogicStack['goto'])) {
                    $tree['goto'] = $nextLogicStack['goto'];
                    $tree['type'] = $nextLogicStack['type'];
                }
                unset($this->logicStacks[$logicStackKeys[$i]]);
                $this->logicStacks[$logicStackKeys[$i + 1]] = $tree;
                break;
            }
        }
    }

    protected function _combineLogicByGotoIndex($index)
    {
        krsort($this->logicStacks);
        $executeFlag = true;
        $execute = [];
        $storage = [];
        foreach ($this->logicStacks as $key => $value) {
            if (isset($value['goto']) && $value['goto'] > $index) {
                $executeFlag = false;
            }
            if ($executeFlag) {
                $execute[$key] = $value;
            } else {
                $storage[$key] = $value;
            }
        }
        $result = '';
        if (!empty($execute)) {
            $this->logicStacks = $execute;
            $result = $this->_combineLogic();
        }
        $this->logicStacks = $storage;
        return $result;
    }

    protected function _combineLogicByParserIndex($index)
    {
        ksort($this->logicStacks);
        $executeFlag = true;
        $execute = [];
        $storage = [];
        foreach ($this->logicStacks as $key => $value) {
            if ($key > $index) {
                $executeFlag = false;
            }
            if ($executeFlag) {
                $execute[$key] = $value;
            } else {
                $storage[$key] = $value;
            }
        }
        $result = '';
        if (!empty($execute)) {
            $this->logicStacks = $execute;
            $result = $this->_combineLogic();
        }
        $this->logicStacks = $storage;
        return $result;
    }
}


================================================
FILE: src/Helper/Reveal.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/11
 * Time: 上午10:13
 */

namespace Irelance\Mozjs34\Helper;


use Irelance\Mozjs34\Constant;

trait Reveal
{
    public function printSummaries()
    {
        if (count($this->summaries)) {
            echo '---------------Summaries---------------', CLIENT_EOL;
            foreach ($this->summaries as $key => $value) {
                echo $key, ' : ', $value, CLIENT_EOL;
            }
            echo '---------------------------------------', CLIENT_EOL;
        }
    }

    public function printOperations()
    {
        echo '---------------Operations--------------', CLIENT_EOL;
        foreach ($this->operations as $key => $operation) {
            $op = Constant::_Opcode[$operation['id']];
            echo '[', $key, ']', $op['op'], json_encode($operation['params']), ' pop: ', $operation['pop'], ' push: ', $operation['push'], ' byte: ', $operation['length'], CLIENT_EOL;
        }
        echo '---------------------------------------', CLIENT_EOL;
    }

    public function printNodes()
    {
        echo '-----------------Nodes-----------------', CLIENT_EOL;
        echo implode(', ', $this->nodes), CLIENT_EOL;
        echo '---------------------------------------', CLIENT_EOL;
    }

    public function printAtoms()
    {
        if (count($this->atoms)) {
            echo '-----------------Atoms-----------------', CLIENT_EOL;
            foreach ($this->atoms as $key => $value) {
                echo $key, ' : ', $value, CLIENT_EOL;
            }
            echo '---------------------------------------', CLIENT_EOL;
        }
    }

    public function printConsts()
    {
        if (count($this->consts)) {
            echo '-----------------Consts----------------', CLIENT_EOL;
            foreach ($this->consts as $key => $const) {
                echo $key, ' : [', $const['type'], ']', $const['value'], CLIENT_EOL;
            }
            echo '---------------------------------------', CLIENT_EOL;
        }
    }

    public function printObjects()
    {
        if (count($this->objects)) {
            echo '-----------------Objects---------------', CLIENT_EOL;
            foreach ($this->objects as $object) {
                echo json_encode($object), CLIENT_EOL;
            }
            echo '---------------------------------------', CLIENT_EOL;
        }
    }

    public function printRegexps()
    {
        if (count($this->regexps)) {
            echo '-----------------Regexps---------------', CLIENT_EOL;
            foreach ($this->regexps as $regexp) {
                echo $regexp['source'], CLIENT_EOL;
            }
            echo '---------------------------------------', CLIENT_EOL;
        }
    }

    public function printTryNote()
    {
        if (count($this->tryNotes)) {
            echo '-----------------Objects---------------', CLIENT_EOL;
            foreach ($this->tryNotes as $tryNote) {
                echo json_encode($tryNote), CLIENT_EOL;
            }
            echo '---------------------------------------', CLIENT_EOL;
        }
    }

    public function printScopeNote()
    {
        if (count($this->scopeNotes)) {
            echo '---------------ScopeNotes---------------', CLIENT_EOL;
            foreach ($this->scopeNotes as $id => $scopeNote) {
                echo $id, ' : ', json_encode($scopeNote), CLIENT_EOL;
            }
            echo '---------------------------------------', CLIENT_EOL;
        }
    }

    public function printProperties(array $types)
    {
        foreach ($types as $type) {
            $call = 'print' . $type;
            if (method_exists($this, $call)) {
                $this->$call();
            }
        }
    }

    public function printContent()
    {
        foreach ($this->operations as $key => $operation) {
            if (!$this->operations[$key]['isCover']) {
                if ($this->isDebug) {
                    echo $key, CLIENT_EOL;
                }
                $this->revealOperation($operation);
                $this->operations[$key]['isCover'] = true;
            }
        }

        ksort($this->storageScript);
        $scriptKeys = array_keys($this->storageScript);
        $scriptKeysCount = count($scriptKeys);
        echo '----------------Content----------------', CLIENT_EOL;
        for ($i = 0; $i < $scriptKeysCount; $i++) {
            $script = $this->storageScript[$scriptKeys[$i]];
            if ($this->isDebug) {
                echo '[', $scriptKeys[$i] / 2, ']', $script['value'], CLIENT_EOL;
            } else {
                echo $script['value'], CLIENT_EOL;
            }
        }
        echo '---------------------------------------', CLIENT_EOL;
    }

    public function printArgv()
    {
        echo '------------------Argv------------------', CLIENT_EOL;
        echo implode(',', $this->argvs), CLIENT_EOL;
        echo '---------------------------------------', CLIENT_EOL;
    }
}


================================================
FILE: src/Helper/Stack.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/12
 * Time: 下午1:43
 */

namespace Irelance\Mozjs34\Helper;


class Stack
{
    public $type;
    public $name;
    public $value;//raw input value
    public $script;//raw input script

    public function __construct(array $props)
    {
        foreach ($props as $prop => $value) {
            $this->$prop = $value;
        }
    }

    public function getValue()
    {
        if ($this->name) {
            return $this->name;
        }
        return $this->getScript();
    }

    public function getScript()
    {
        if ($this->script) {
            return $this->script;
        }
        $this->script = self::renderBase($this);
        return $this->script;
    }

    public static function renderBase(self $input)
    {
        switch ($input->type) {
            case 'script':
                return $input->script;
            case 'function':
                return 'function () { __FUNC_' . $input->value . '__ }';
            case 'string':
                return '"' . $input->value . '"';
            case 'object':
                return self::renderObject($input->value);
            case 'array':
                return self::renderArray($input->value);
            case 'number':
            case 'boolean':
            case 'null':
            case 'undefined':
            case 'regexp':
        }
        return $input->value;
    }

    public static function renderArray($array)
    {
        $result = '[';
        foreach ($array as $item) {
            $result .= $item->getValue() . ',';
        }
        $resultLen = strlen($result);
        if ($resultLen>1) {
            $result = substr($result, 0, $resultLen - 1);
        }
        $result .= ']';
        return $result;
    }

    public static function renderObject($object)
    {
        $result = '{';
        foreach ($object as $key => $value) {
            $result .= $key . ':';
            $result .= $value->getValue() . ',';
        }
        $resultLen = strlen($result);
        if ($resultLen>1) {
            $result = substr($result, 0, $resultLen - 1);
        }
        $result .= '}';
        return $result;
    }
}


================================================
FILE: src/Xdr/Atom.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/10
 * Time: 上午11:30
 */

namespace Irelance\Mozjs34\Xdr;

trait Atom
{
    protected function getLatin1Chars($length)
    {
        $end = $this->parseIndex + $length;
        $atom = '';
        for (; $this->parseIndex < $end; $this->parseIndex++) {
            $atom .= chr($this->bytecodes[$this->parseIndex]);
        }
        return $atom;
    }

    protected function getTwoByteChar()
    {
        $char = '\u' . dechex($this->bytecodes[$this->parseIndex + 1]) . dechex($this->bytecodes[$this->parseIndex]);
        $this->parseIndex += 2;
        return $char;
    }

    protected function getTwoByteChars($length)
    {
        $atom = '';
        for ($i = 0; $i < $length; $i++) {
            $atom .= $this->getTwoByteChar();
        }
        return json_decode('"' . $atom . '"');
    }

    public function XDRAtom()
    {
        $lengthAndEncoding = $this->todec();
        $hasLatin1Chars = $lengthAndEncoding & 1;
        $length = $lengthAndEncoding >> 1;
        if ($hasLatin1Chars) {
            $atom = $this->getLatin1Chars($length);
        } else {
            $atom = $this->getTwoByteChars($length);
        }
        return $atom;
    }
}


================================================
FILE: src/Xdr/Common.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/10
 * Time: 上午11:30
 */

namespace Irelance\Mozjs34\Xdr;

use Irelance\Mozjs34\Constant;


trait Common
{
    protected function getRawHex($length)
    {
        $end = $this->parseIndex + $length;
        $result = '';
        for (; $this->parseIndex < $end; $this->parseIndex++) {
            $result .= sprintf('%02s', dechex($this->bytecodes[$this->parseIndex]));
        }
        return $result;
    }

    protected function getCString()
    {
        $result = '';
        while ($this->bytecodes[$this->parseIndex]) {
            $result .= chr($this->bytecodes[$this->parseIndex]);
            $this->parseIndex++;
        }
        $this->parseIndex++;
        return $result;
    }

    protected function todec($length = 4)//length include start
    {
        return $this->littleEndian2Dec($length);
    }

    protected function littleEndian2Dec($length)
    {
        $result = '';
        for ($i = $this->parseIndex + $length - 1; $i >= $this->parseIndex; $i--) {
            $result .= sprintf('%02s', dechex($this->bytecodes[$i]));
        }
        $this->parseIndex += $length;
        return hexdec($result);
    }

    protected function bigEndian2Dec($length)
    {
        $end = $this->parseIndex + $length;
        $result = '';
        for (; $this->parseIndex < $end; $this->parseIndex++) {
            $result .= sprintf('%02s', dechex($this->bytecodes[$this->parseIndex]));
        }
        return hexdec($result);
    }

    protected function uInt32ToInt32($num)
    {
        return unpack('l', pack('L', $num))[1];
    }

    protected function uIntToInt($num, $bit)
    {
        $half = 1 << ($bit - 1);
        if ($num <= $half) {
            return $num;
        }
        $max = (1 << $bit) - 1;
        return -(($num - 1) ^ $max);
    }

    public function xdrConst()
    {
        $type = $this->todec();
        $const = [
            'type' => Constant::_ConstTag[$type],
        ];
        switch ($type) {
            case 0:
                $const['value'] = $this->todec();
                break;
            case 1:
                $value = unpack('d', pack('H*', $this->getRawHex(8)));
                $const['value'] = $value[1];
                break;
            case 2:
                $const['value'] = $this->XDRAtom();
                break;
            case 3:
                $const['value'] = true;
                break;
            case 4:
                $const['value'] = false;
                break;
            case 5:
                $const['value'] = null;
                break;
            case 6:
                $object = $this->xdrCK_JSObject();
                $const['value'] = "__OBJECT__";
                $const['extra'] = $object;
                break;
            case 7:
                $const['value'] = "__VOID__";
                break;
            case 8:
                $const['value'] = "__HOLE__";
                break;
            default:
                $const['value'] = "__ERROR__";
                break;
        }
        return $const;
    }

    public function XDRInterpretedFunction()
    {
        $result = ['name' => ''];
        $firstword = $this->todec();
        if ($firstword & Constant::_FirstWordFlag['HasAtom']) {
            $result['name'] = $this->XDRAtom();
        }
        $flagsword = $this->todec();
        if ($firstword & Constant::_FirstWordFlag['IsLazy']) {
            $this->XDRLazyScript();
            $result['type'] = 'lazy';
        } else {
            $result['type'] = 'block';
            $result['contextIndex'] = $this->XDRScript()->index;
        }
        return $result;
    }

    public function XDRLazyFreeVariables()
    {
        //for 0 -> numFreeVariables
        //$atom=$this->XDRAtom();
    }

    public function XDRLazyScript()
    {
        //XDRLazyScript
        $begin = $this->todec();
        $end = $this->todec();
        $lineno = $this->todec();
        $column = $this->todec();
        $packedFields = $this->todec(8);
        $this->XDRLazyFreeVariables();
    }
}


================================================
FILE: src/Xdr/ObjectXdr.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/10
 * Time: 上午11:49
 */

namespace Irelance\Mozjs34\Xdr;


trait ObjectXdr
{
    public function xdrObjectExtra($objectType)
    {
        $result = 'xdr';
        switch ($objectType) {
            case 'CK_BlockObject':
            case 'CK_WithObject':
            case 'CK_JSFunction':
            case 'CK_JSObject':
                $result .= $objectType;
                break;
            default:
                $result .= 'CK_Not';
                break;
        }
        return $this->$result();
    }

    protected function xdrCK_Not()
    {
        return [];
    }

    protected function xdrCK_BlockObject()
    {
        $result = [
            'enclosingStaticScopeIndex' => $this->todec(),
            'count' => $this->todec(),
            'offset' => $this->todec(),
            'atoms' => [],
        ];
        for ($i = 0; $i < $result['count']; $i++) {
            $result['atoms'][] = [
                'atom' => $this->XDRAtom(),
                'aliased' => $this->todec(),
            ];
        }

        return $result;
    }

    protected function xdrCK_WithObject()
    {
        return [
            'enclosingStaticScopeIndex' => $this->todec(),
        ];
    }

    protected function xdrCK_JSFunction()
    {
        return array_merge([
            'funEnclosingScopeIndex' => $funEnclosingScopeIndex = $this->todec(),
        ],$this->XDRInterpretedFunction());
    }

    public function xdrCK_JSObject()
    {
        $result = [];
        $result['isArray'] = $isArray = $this->todec();
        $this->todec();//isArray ? length : kind
        $result['capacity'] = $capacity = $this->todec();
        $initialized = $this->todec();
        $result['initialized'] = [];
        for ($i = 0; $i < $initialized; $i++) {
            $result['initialized'][] = $tmpValue = $this->xdrConst();
        }
        $nslot = $this->todec();
        $result['nslot'] = [];
        for ($i = 0; $i < $nslot; $i++) {
            $idType = $this->todec();
            if ($idType == JSID_TYPE_STRING) {
                $key = $this->XDRAtom();
            } else {
                $key = $this->todec();
            }
            $val = $this->xdrConst();
            $result['nslot'][$key] = $val;
        }
        $isSingletonTyped = $this->todec();
        $frozen = $this->todec();
        if ($isArray) {
            $copyOnWrite = $this->todec();
        }
        return $result;
    }

}


================================================
FILE: src/Xdr/Operation.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/11
 * Time: 上午11:21
 */

namespace Irelance\Mozjs34\Xdr;

use Irelance\Mozjs34\Constant;

trait Operation
{
    public function parserOperation()
    {
        $op = Constant::_Opcode[$this->bytecodes[$this->parseIndex]];
        $result = [
            'id' => $op['val'],
            'name' => $op['op'],
            'parserIndex' => $this->parseIndex,
            'params' => [],
            'length' => $op['len'],
            'image' => $op['image'],
            'push' => $op['def'],
            'pop' => $op['use'],
            'isCover' => false,
        ];
        $this->parseIndex++;
        switch ($op['op']) {
            case 'JSOP_ENTERWITH':
                $result['params']['staticWithIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_GOTO':
            case 'JSOP_IFEQ':
            case 'JSOP_IFNE':
            case 'JSOP_OR':
            case 'JSOP_AND':
            case 'JSOP_LABEL':
            case 'JSOP_GOSUB':
            case 'JSOP_CASE':
            case 'JSOP_DEFAULT':
            case 'JSOP_BACKPATCH':
                $result['params']['offset'] = $this->uInt32ToInt32($this->bigEndian2Dec(4));
                break;
            case 'JSOP_CALL':
            case 'JSOP_FUNAPPLY':
            case 'JSOP_NEW':
            case 'JSOP_FUNCALL':
            case 'JSOP_EVAL':
                $result['params']['argc'] = $this->bigEndian2Dec(2);
                break;
            case 'JSOP_GETARG':
            case 'JSOP_SETARG':
                $result['params']['argno'] = $this->bigEndian2Dec(2);
                break;
            case 'JSOP_PICK':
                $result['params']['n'] = $this->bigEndian2Dec(1);
                break;
            case 'JSOP_POPN':
                $result['params']['n'] = $this->bigEndian2Dec(2);
                break;
            case 'JSOP_DUPAT':
                $result['params']['n'] = $this->bigEndian2Dec(3);
                break;
            case 'JSOP_SETCONST':
            case 'JSOP_DELNAME':
            case 'JSOP_DELPROP':
            case 'JSOP_GETPROP':
            case 'JSOP_SETPROP':
            case 'JSOP_INITPROP':
            case 'JSOP_NAME':
            case 'JSOP_INITPROP_GETTER':
            case 'JSOP_INITPROP_SETTER':
            case 'JSOP_BINDNAME':
            case 'JSOP_SETNAME':
            case 'JSOP_DEFCONST':
            case 'JSOP_DEFVAR':
            case 'JSOP_GETINTRINSIC':
            case 'JSOP_SETINTRINSIC':
            case 'JSOP_BINDINTRINSIC':
            case 'JSOP_GETGNAME':
            case 'JSOP_SETGNAME':
            case 'JSOP_CALLPROP':
            case 'JSOP_GETXPROP':
            case 'JSOP_BINDGNAME':
            case 'JSOP_LENGTH':
            case 'JSOP_IMPLICITTHIS':
                $result['params']['nameIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_DOUBLE':
                $result['params']['constIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_STRING':
                $result['params']['atomIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_OBJECT':
            case 'JSOP_CALLSITEOBJ':
            case 'JSOP_NEWARRAY_COPYONWRITE':
                $result['params']['objectIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_DEFFUN':
            case 'JSOP_LAMBDA':
            case 'JSOP_LAMBDA_ARROW':
                $result['params']['funcIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_REGEXP':
                $result['params']['regexpIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_PUSHBLOCKSCOPE':
                $result['params']['staticBlockObjectIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_TABLESWITCH':
                $result['params']['len'] = $this->uInt32ToInt32($this->bigEndian2Dec(4));
                $result['params']['low'] = $this->uInt32ToInt32($this->bigEndian2Dec(4));
                $result['params']['high'] = $this->uInt32ToInt32($this->bigEndian2Dec(4));
                $result['params']['offset'] = [];
                $end = $result['params']['high'] - $result['params']['low'];
                for ($i = 0; $i <= $end; $i++) {
                    $result['params']['offset'][$i] = $this->uInt32ToInt32($this->bigEndian2Dec(4));
                }
                break;
            case 'JSOP_ITER':
                $result['params']['flags'] = $this->bigEndian2Dec(1);
                break;
            case 'JSOP_GETLOCAL'://todo uint32_t localno but op len is 4
            case 'JSOP_SETLOCAL'://todo uint32_t localno but op len is 4
                $result['params']['localno'] = $this->bigEndian2Dec(3);
                break;
            case 'JSOP_INT8':
                $result['params']['val'] = $this->uIntToInt($this->bigEndian2Dec(1), 8);
                break;
            case 'JSOP_UINT16':
                $result['params']['val'] = $this->bigEndian2Dec(2);
                break;
            case 'JSOP_UINT24':
                $result['params']['val'] = $this->bigEndian2Dec(3);
                break;
            case 'JSOP_INT32':
                $result['params']['val'] = $this->uInt32ToInt32($this->bigEndian2Dec(4));
                break;
            case 'JSOP_NEWINIT':
                $result['params']['kind'] = $this->bigEndian2Dec(1);
                $result['params']['extra'] = $this->bigEndian2Dec(3);
                break;
            case 'JSOP_NEWARRAY':
                $result['params']['length'] = $this->bigEndian2Dec(3);
                break;
            case 'JSOP_NEWOBJECT':
                $result['params']['baseobjIndex'] = $this->bigEndian2Dec(4);
                break;
            case 'JSOP_INITELEM_ARRAY':
                $result['params']['index'] = $this->bigEndian2Dec(3);
                break;
            case 'JSOP_LINENO':
                $result['params']['lineno'] = $this->bigEndian2Dec(2);
                break;
            case 'JSOP_GETALIASEDVAR':
            case 'JSOP_SETALIASEDVAR':
                $result['params']['hops'] = $this->bigEndian2Dec(1);
                $result['params']['slot'] = $this->bigEndian2Dec(3);
                break;
            case 'JSOP_LOOPENTRY':
                $result['params']['BITFIELD'] = $this->bigEndian2Dec(1);
                $result['params']['depth'] = $result['params']['BITFIELD'] - 128;
                break;
        }
        return $result;
    }
}


================================================
FILE: src/Xdr/Scope.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/10
 * Time: 上午11:47
 */

namespace Irelance\Mozjs34\Xdr;
/**
 * @method \Irelance\Mozjs34\Xdr\Common todec(int $length = 4)
 *
 * @property integer $parseIndex
 * @property array $bytecodes
 */
trait Scope
{
    protected function XDRSizedBindingNames()
    {
        $length = $this->todec();
        $result = [];
        for ($i = 0; $i < $length; $i++) {
            $u8 = $this->todec(1);
            $hasAtom = $u8 >> 1;
            if ($hasAtom) {
                $result[] = $this->XDRAtom();
            }
        }
        return $result;
    }

    public function xdrScopeExtra($scopeKind)
    {
        $result = 'xdr';
        switch ($scopeKind) {
            case 'Function':
                $result .= 'Function';
                break;
            case 'FunctionBodyVar':
            case 'ParameterExpressionVar':
                $result .= 'Var';
                break;
            case 'Lexical':
            case 'SimpleCatch':
            case 'Catch':
            case 'NamedLambda':
            case 'StrictNamedLambda':
                $result .= 'Lexical';
                break;
            case 'With':
                $result .= 'With';
                break;
            case 'Eval':
            case 'StrictEval':
                $result .= 'Eval';
                break;
            case 'Global':
            case 'NonSyntactic':
                $result .= 'Global';
                break;
            case 'Module':
            default:
                $result .= 'Not';
        }
        return $this->$result();
    }

    protected function xdrNot()
    {
        return [];
    }

    protected function xdrWith()
    {
        return [];
    }

    protected function xdrLexical()
    {
        return [
            'bindingNames' => $this->XDRSizedBindingNames(),
            'constStart' => $this->todec(),
            'firstFrameSlot' => $this->todec(),
            'nextFrameSlot' => $this->todec()
        ];
    }

    protected function xdrFunction()
    {
        return [
            'bindingNames' => $this->XDRSizedBindingNames(),
            'needsEnvironment' => $this->todec(1),
            'hasParameterExprs' => $this->todec(1),
            'nonPositionalFormalStart' => $this->todec(2),
            'varStart' => $this->todec(2),
            'nextFrameSlot' => $this->todec(),
        ];
    }

    protected function xdrVar()
    {
        return [
            'bindingNames' => $this->XDRSizedBindingNames(),
            'needsEnvironment' => $this->todec(1),
            'firstFrameSlot' => $this->todec(),
            'nextFrameSlot' => $this->todec()
        ];
    }

    protected function xdrGlobal()
    {
        return [
            'bindingNames' => $this->XDRSizedBindingNames(),
            'letStart' => $this->todec(),
            'constStart' => $this->todec(),
        ];
    }

    protected function xdrEval()
    {
        return [
            'bindingNames' => $this->XDRSizedBindingNames(),
            'length' => $this->todec(),
        ];
    }
}


================================================
FILE: src/Xdr/Script.php
================================================
<?php
/**
 * Created by PhpStorm.
 * User: irelance
 * Date: 2017/10/10
 * Time: 上午11:30
 */

namespace Irelance\Mozjs34\Xdr;

use Irelance\Mozjs34\Context;
use Irelance\Mozjs34\Constant;

/**
 * @method \Irelance\Mozjs34\Xdr\Common todec(int $length = 4)
 *
 * @property integer $parseIndex
 * @property array $bytecodes
 */
trait Script
{

    protected function parserHeader(Context $context)
    {
        $nargs = $this->todec(2);
        $context->addSummary('nargs', $nargs);
        $context->addSummary('nblocklocals', $this->todec(2));
        $nvars = $this->todec();
        $context->addSummary('nvars', $nvars);
        $context->addSummary('length', $this->todec());
        $context->addSummary('prologLength', $this->todec());
        $context->addSummary('version', $this->todec());
        $context->addSummary('natoms', $this->todec());
        $context->addSummary('nsrcnotes', $this->todec());
        $context->addSummary('nconsts', $this->todec());
        $context->addSummary('nobjects', $this->todec());
        $context->addSummary('nregexps', $this->todec());
        $context->addSummary('ntrynotes', $this->todec());
        $context->addSummary('nblockscopes', $this->todec());
        $context->addSummary('nTypeSets', $this->todec());
        $context->addSummary('funLength', $this->todec());
        $scriptBit = $this->todec();
        $context->addSummary('scriptBits', $scriptBit);
        $scriptBits = array_flip(Constant::_ScriptBits);
        if ($scriptBit & (1 << $scriptBits['OwnSource'])) {
            $context->addSummary('hasSource', $this->todec(1));
            $context->addSummary('retrievable', $this->todec(1));
            if($context->getSummary('hasSource') && !$context->getSummary('retirevable')) {
                $context->addSummary('sourceLength', $this->todec());
                $context->addSummary('sourcecompressedLength', $this->todec());
                $context->addSummary('argumentsNotIncluded', $this->todec(1));
                $context->addSummary(
                    'sourceBytes',
                    $this->getRawHex(
                        $context->getSummary('sourcecompressedLength') ?
                            $context->getSummary('sourcecompressedLength') :
                            $context->getSummary('sourceLength') * 2
                    )
                    );
            }

            $context->addSummary('hasSourceMap', $this->todec(1));
            if($context->getSummary('hasSourceMap')) {
                $context->addSummary('sourceMapURLLen', $this->todec());
                $context->addSummary('sourceMapURL', $this->getRawHex($context->getSummary('sourceMapURLLen') * 2));
            }

            $context->addSummary('haveDisplayURL', $this->todec(1));
            if($context->getSummary('haveDisplayURL')) {
                $context->addSummary('displayURLLen', $this->todec());
                $context->addSummary('displayURL', $this->getRawHex($context->getSummary('displayURLLen')));
            }

            $context->addSummary('haveFilename', $this->todec(1));
            if($context->getSummary('haveFilename')) {
                $context->addSummary('buildPath', $this->getCString());
            }
            
        }
        $nameCount = $nargs + $nvars;
        for ($i = 0; $i < $nameCount; $i++) {
            $atom = $this->XDRAtom();
            $context->addArgv($atom);
        }
        for ($i = 0; $i < $nameCount; $i++) {
            $u8 = $this->todec(1);
        }
        $context->addSummary('sourceStart_', $this->todec());
        $context->addSummary('sourceEnd_', $this->todec());
        $context->addSummary('lineno', $this->todec());
        $context->addSummary('column', $this->todec());
        $context->addSummary('nslots', $this->todec());
        $context->addSummary('staticLevel', $this->todec());
    }

    protected function parserScript(Context $context)
    {
        $end = $this->parseIndex + $context->getSummary('length');
        for (; $this->parseIndex < $end;) {
            $context->addOperation($this->parseIndex, $this->parserOperation());
        }
        $this->parseIndex = $end;
    }

    protected function parserSrcNodes(Context $context)
    {
        $end = $this->parseIndex + $context->getSummary('nsrcnotes');
        for (; $this->parseIndex < $end; $this->parseIndex++) {
            $context->addNode($this->bytecodes[$this->parseIndex]);
        }
    }

    protected function parserAtoms(Context $context)
    {
        if ($natoms = $context->getSummary('natoms')) {
            for ($i = 0; $i < $natoms; $i++) {
                $context->addAtom($this->XDRAtom());
            }
        }
    }

    protected function parseConsts(Context $context)
    {
        if ($nconsts = $context->getSummary('nconsts')) {
            for ($i = 0; $i < $nconsts; $i++) {
                $context->addConst($this->xdrConst());
            }
        }
    }

    protected function parserObject(Context $context)
    {
        $context->addObject(
            $classKind = Constant::_Class[$this->todec()],
            $extra = $this->xdrObjectExtra($classKind)
        );
    }

    protected function parserObjects(Context $context)
    {
        if ($nobjects = $context->getSummary('nobjects')) {
            for ($i = 0; $i < $nobjects; $i++) {
                $this->parserObject($context);
            }
        }
    }

    protected function parserRegexps(Context $context)
    {
        if ($nregexps = $context->getSummary('nregexps')) {
            for ($i = 0; $i < $nregexps; $i++) {
                $context->addRegexp(
                    $source = $this->XDRAtom(),
                    $flagsword = $this->todec()
                );
            }
        }
    }

    protected function parserTryNotes(Context $context)
    {
        if ($ntrynotes = $context->getSummary('ntrynotes')) {
            for ($i = 0; $i < $ntrynotes; $i++) {
                $context->addTryNote(
                    $kind = $this->todec(1),
                    $stackDepth = $this->todec(),
                    $start = $this->todec(),
                    $length = $this->todec()
                );
            }
        }
    }

    protected function parserScopeNotes(Context $context)
    {
        if ($nscopeNotes = $context->getSummary('nblockscopes')) {
            for ($i = 0; $i < $nscopeNotes; $i++) {
                $context->addScopeNote(
                    $index = $this->todec(),
                    $start = $this->todec(),
                    $length = $this->todec(),
                    $parent = $this->todec()
                );
            }
        }
    }

    protected function parserHasLazyScript(Context $context)
    {
        $scriptBits = array_flip(Constant::_ScriptBits);
        $HasLazyScript = $scriptBits['HasLazyScript'];
        if ($context->getSummary('scriptBits') & (1 << $HasLazyScript)) {
            $packedFields = $this->todec(8);
            $context->addHasLazyScript($packedFields);
            $this->XDRLazyFreeVariables();
        }
    }

    public function XDRScript()
    {
        $context = new Context();
        $index = count($this->contexts);
        $this->contexts[] = $context;
        $context->index = $index;
        $this->parseScriptIndex = $index;
        $context->decompile = $this;
        $this->parserHeader($context);//header storage the base info of a context, if jsc compile with no setSourceIsLazy(true), raw source save here
        $this->parserScript($context);//get the operations and parse to script (maybe not good enough to parse here)
        $this->parserSrcNodes($context);
        $this->parserAtoms($context);//this section save strings
        $this->parseConsts($context);
        $this->parserObjects($context);//this section save local simple objects
        $this->parserRegexps($context);
        $this->parserTryNotes($context);
        $this->parserScopeNotes($context);//this section save block scope info
        $this->parserHasLazyScript($context);
        return $context;
    }
}
Download .txt
gitextract_il3n6s28/

├── .gitignore
├── composer.json
├── readme.md
├── run.php
├── scan.php
└── src/
    ├── Constant.php
    ├── Context.php
    ├── Decompile.php
    ├── Helper/
    │   ├── Operation.php
    │   ├── Reveal.php
    │   └── Stack.php
    └── Xdr/
        ├── Atom.php
        ├── Common.php
        ├── ObjectXdr.php
        ├── Operation.php
        ├── Scope.php
        └── Script.php
Download .txt
SYMBOL INDEX (122 symbols across 12 files)

FILE: src/Constant.php
  class Constant (line 34) | class Constant

FILE: src/Context.php
  class Context (line 15) | class Context
    method addArgv (line 39) | public function addArgv($value)
    method addSummary (line 44) | public function addSummary($key, $value)
    method addOperation (line 53) | public function addOperation($parserIndex, array $operation)
    method addNode (line 58) | public function addNode($node)
    method addAtom (line 63) | public function addAtom($atom)
    method addConst (line 68) | public function addConst($const)
    method addObject (line 73) | public function addObject($classKind, array $extra)
    method addRegexp (line 78) | public function addRegexp($source, $flagsword)
    method addTryNote (line 86) | public function addTryNote($kind, $stackDepth, $start, $length)
    method addScopeNote (line 91) | public function addScopeNote($index, $start, $length, $parent)
    method addHasLazyScript (line 96) | public function addHasLazyScript($packedFields)
    method getSummary (line 101) | public function getSummary($key)
    method pushStack (line 109) | public function pushStack($stack)
    method popStack (line 120) | public function popStack()
    method writeScript (line 127) | public function writeScript($parserIndex, $string, $offset = 0)
    method appendScript (line 132) | public function appendScript($parserIndex, $string, $offset = 0)
    method getScript (line 141) | public function getScript($parserIndex, $offset = 0)
    method dropScript (line 149) | public function dropScript($parserIndex, $offset = 0)

FILE: src/Decompile.php
  class Decompile (line 17) | class Decompile
    method __construct (line 36) | public function __construct($filename)
    method __destruct (line 42) | public function __destruct()
    method init (line 47) | public function init()
    method parserVersion (line 58) | protected function parserVersion()
    method run (line 65) | public function run()
    method runResult (line 71) | public function runResult()
    method getContexts (line 79) | public function getContexts()
    method setLocalVariable (line 86) | public function setLocalVariable($index, $value)
    method getLocalVariable (line 91) | public function getLocalVariable($index)
    method setAliasedVariable (line 101) | public function setAliasedVariable($hops, $slot, $value)
    method getAliasedVariable (line 109) | public function getAliasedVariable($hops, $slot)
    method setGlobalVariable (line 119) | public function setGlobalVariable($key, $value)
    method getGlobalVariable (line 124) | public function getGlobalVariable($key)

FILE: src/Helper/Operation.php
  type Operation (line 17) | trait Operation
    method gotoNextOperation (line 21) | protected function gotoNextOperation($nextOperation)
    method getNextOperation (line 33) | public function getNextOperation($operation)
    method revealOperations (line 42) | public function revealOperations($start, $end, $conditons = [], $isCov...
    method hasOperation (line 60) | protected function hasOperation($start, $end, $name)
    method findFirstOperation (line 75) | protected function findFirstOperation($name, $start = null, $end = null)
    method revealOperation (line 93) | public function revealOperation($operation, $conditons = [])
    method _renderSwitch (line 866) | protected function _renderSwitch($contents, $defaultIndex)
    method getLogicValue (line 883) | protected function getLogicValue($operation, Stack $val)
    method _getLoopGoto (line 892) | protected function _getLoopGoto($operation)
    method _getLoopLogic (line 905) | protected function _getLoopLogic($entry)
    method _getBranchGoto (line 920) | protected function _getBranchGoto($operation)
    method _getBranchBreak (line 933) | protected function _getBranchBreak($goto)
    method _getBranchContinue (line 944) | protected function _getBranchContinue($goto)
    method _combineLogic (line 956) | protected function _combineLogic()
    method _getLogicScript (line 977) | protected function _getLogicScript($stack)
    method _combineLogicUnit (line 999) | protected function _combineLogicUnit()
    method _combineLogicByGotoIndex (line 1042) | protected function _combineLogicByGotoIndex($index)
    method _combineLogicByParserIndex (line 1067) | protected function _combineLogicByParserIndex($index)

FILE: src/Helper/Reveal.php
  type Reveal (line 14) | trait Reveal
    method printSummaries (line 16) | public function printSummaries()
    method printOperations (line 27) | public function printOperations()
    method printNodes (line 37) | public function printNodes()
    method printAtoms (line 44) | public function printAtoms()
    method printConsts (line 55) | public function printConsts()
    method printObjects (line 66) | public function printObjects()
    method printRegexps (line 77) | public function printRegexps()
    method printTryNote (line 88) | public function printTryNote()
    method printScopeNote (line 99) | public function printScopeNote()
    method printProperties (line 110) | public function printProperties(array $types)
    method printContent (line 120) | public function printContent()
    method printArgv (line 147) | public function printArgv()

FILE: src/Helper/Stack.php
  class Stack (line 12) | class Stack
    method __construct (line 19) | public function __construct(array $props)
    method getValue (line 26) | public function getValue()
    method getScript (line 34) | public function getScript()
    method renderBase (line 43) | public static function renderBase(self $input)
    method renderArray (line 65) | public static function renderArray($array)
    method renderObject (line 79) | public static function renderObject($object)

FILE: src/Xdr/Atom.php
  type Atom (line 11) | trait Atom
    method getLatin1Chars (line 13) | protected function getLatin1Chars($length)
    method getTwoByteChar (line 23) | protected function getTwoByteChar()
    method getTwoByteChars (line 30) | protected function getTwoByteChars($length)
    method XDRAtom (line 39) | public function XDRAtom()

FILE: src/Xdr/Common.php
  type Common (line 14) | trait Common
    method getRawHex (line 16) | protected function getRawHex($length)
    method getCString (line 26) | protected function getCString()
    method todec (line 37) | protected function todec($length = 4)//length include start
    method littleEndian2Dec (line 42) | protected function littleEndian2Dec($length)
    method bigEndian2Dec (line 52) | protected function bigEndian2Dec($length)
    method uInt32ToInt32 (line 62) | protected function uInt32ToInt32($num)
    method uIntToInt (line 67) | protected function uIntToInt($num, $bit)
    method xdrConst (line 77) | public function xdrConst()
    method XDRInterpretedFunction (line 121) | public function XDRInterpretedFunction()
    method XDRLazyFreeVariables (line 139) | public function XDRLazyFreeVariables()
    method XDRLazyScript (line 145) | public function XDRLazyScript()

FILE: src/Xdr/ObjectXdr.php
  type ObjectXdr (line 12) | trait ObjectXdr
    method xdrObjectExtra (line 14) | public function xdrObjectExtra($objectType)
    method xdrCK_Not (line 31) | protected function xdrCK_Not()
    method xdrCK_BlockObject (line 36) | protected function xdrCK_BlockObject()
    method xdrCK_WithObject (line 54) | protected function xdrCK_WithObject()
    method xdrCK_JSFunction (line 61) | protected function xdrCK_JSFunction()
    method xdrCK_JSObject (line 68) | public function xdrCK_JSObject()

FILE: src/Xdr/Operation.php
  type Operation (line 13) | trait Operation
    method parserOperation (line 15) | public function parserOperation()

FILE: src/Xdr/Scope.php
  type Scope (line 16) | trait Scope
    method XDRSizedBindingNames (line 18) | protected function XDRSizedBindingNames()
    method xdrScopeExtra (line 32) | public function xdrScopeExtra($scopeKind)
    method xdrNot (line 68) | protected function xdrNot()
    method xdrWith (line 73) | protected function xdrWith()
    method xdrLexical (line 78) | protected function xdrLexical()
    method xdrFunction (line 88) | protected function xdrFunction()
    method xdrVar (line 100) | protected function xdrVar()
    method xdrGlobal (line 110) | protected function xdrGlobal()
    method xdrEval (line 119) | protected function xdrEval()

FILE: src/Xdr/Script.php
  type Script (line 20) | trait Script
    method parserHeader (line 23) | protected function parserHeader(Context $context)
    method parserScript (line 96) | protected function parserScript(Context $context)
    method parserSrcNodes (line 105) | protected function parserSrcNodes(Context $context)
    method parserAtoms (line 113) | protected function parserAtoms(Context $context)
    method parseConsts (line 122) | protected function parseConsts(Context $context)
    method parserObject (line 131) | protected function parserObject(Context $context)
    method parserObjects (line 139) | protected function parserObjects(Context $context)
    method parserRegexps (line 148) | protected function parserRegexps(Context $context)
    method parserTryNotes (line 160) | protected function parserTryNotes(Context $context)
    method parserScopeNotes (line 174) | protected function parserScopeNotes(Context $context)
    method parserHasLazyScript (line 188) | protected function parserHasLazyScript(Context $context)
    method XDRScript (line 199) | public function XDRScript()
Condensed preview — 17 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (135K chars).
[
  {
    "path": ".gitignore",
    "chars": 78,
    "preview": "js/\ncompile\nlibmozglue.dylib\nlibmozjs-52.dylib\n.idea/\n\n/vendor/\ncomposer.lock\n"
  },
  {
    "path": "composer.json",
    "chars": 365,
    "preview": "{\n    \"name\": \"irelance/jsc-decompile-mozjs-34\",\n    \"license\": \"proprietary\",\n    \"type\": \"project\",\n    \"authors\": [\n "
  },
  {
    "path": "readme.md",
    "chars": 2596,
    "preview": "# 1.Summary\n\nThis project is a javascript bytecode decoder for mozilla spider-monkey version 34.\n\nThis version may decom"
  },
  {
    "path": "run.php",
    "chars": 930,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/1\n * Time: 上午10:47\n */\ninclude 'vendor/autoload.php"
  },
  {
    "path": "scan.php",
    "chars": 891,
    "preview": "<?php\r\n/**\r\n * Created by PhpStorm.\r\n * User: irelance\r\n * Date: 2018/10/10\r\n * Time: 17:51\r\n */\r\n\r\ninclude 'vendor/auto"
  },
  {
    "path": "src/Constant.php",
    "chars": 39875,
    "preview": "<?php\n\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/9/30\n * Time: 上午10:05\n */\nnamespace Irelance\\Mozjs34;"
  },
  {
    "path": "src/Context.php",
    "chars": 3654,
    "preview": "<?php\n\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/1\n * Time: 下午3:25\n */\nnamespace Irelance\\Mozjs34;\n"
  },
  {
    "path": "src/Decompile.php",
    "chars": 3027,
    "preview": "<?php\n\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/9/20\n * Time: 上午8:04\n *\n * js/src/jsscript.h\n * js/sr"
  },
  {
    "path": "src/Helper/Operation.php",
    "chars": 46220,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/11\n * Time: 上午11:06\n */\n\nnamespace Irelance\\Mozjs34"
  },
  {
    "path": "src/Helper/Reveal.php",
    "chars": 4971,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/11\n * Time: 上午10:13\n */\n\nnamespace Irelance\\Mozjs34"
  },
  {
    "path": "src/Helper/Stack.php",
    "chars": 2203,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/12\n * Time: 下午1:43\n */\n\nnamespace Irelance\\Mozjs34\\"
  },
  {
    "path": "src/Xdr/Atom.php",
    "chars": 1242,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/10\n * Time: 上午11:30\n */\n\nnamespace Irelance\\Mozjs34"
  },
  {
    "path": "src/Xdr/Common.php",
    "chars": 4110,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/10\n * Time: 上午11:30\n */\n\nnamespace Irelance\\Mozjs34"
  },
  {
    "path": "src/Xdr/ObjectXdr.php",
    "chars": 2499,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/10\n * Time: 上午11:49\n */\n\nnamespace Irelance\\Mozjs34"
  },
  {
    "path": "src/Xdr/Operation.php",
    "chars": 6601,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/11\n * Time: 上午11:21\n */\n\nnamespace Irelance\\Mozjs34"
  },
  {
    "path": "src/Xdr/Scope.php",
    "chars": 3099,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/10\n * Time: 上午11:47\n */\n\nnamespace Irelance\\Mozjs34"
  },
  {
    "path": "src/Xdr/Script.php",
    "chars": 8088,
    "preview": "<?php\n/**\n * Created by PhpStorm.\n * User: irelance\n * Date: 2017/10/10\n * Time: 上午11:30\n */\n\nnamespace Irelance\\Mozjs34"
  }
]

About this extraction

This page contains the full source code of the irelance/jsc-decompile-mozjs-34 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 17 files (127.4 KB), approximately 38.6k tokens, and a symbol index with 122 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!