JS-Interpreter Documentation

JS-Interpreter is a sandboxed JavaScript interpreter written in JavaScript. It allows for execution of arbitrary JavaScript code line by line. Execution is completely isolated from the main JavaScript environment. Multiple instances of the JS-Interpreter allow for multi-threaded concurrent JavaScript without the use of Web Workers.

Play with the JS-Interpreter demo.

Get the source code.

Usage

Start by including the two JavaScript source files:

    <script src="acorn.js"></script>
    <script src="interpreter.js"></script>
  

Alternatively, use the compressed bundle (58kb):

    <script src="acorn_interpreter.js"></script>
  

Next, instantiate an interpreter with the JavaScript code that needs to be parsed:

    var myCode = 'var a=1; for(var i=0;i<4;i++){a*=i;} a;';
    var myInterpreter = new Interpreter(myCode);
  

To run the code step by step, call the step function repeatedly until it returns false:

    function nextStep() {
      if (myInterpreter.step()) {
        window.setTimeout(nextStep, 0);
      }
    }
    nextStep();
  

Alternatively, if the code is known to be safe from infinite loops, it may be executed to completion by calling the run function once:

    myInterpreter.run();
  

External API

Similar to the eval function, the result of the last statement executed is available in myInterpreter.value:

    var myInterpreter = new Interpreter('6 * 7');
    myInterpreter.run();
    alert(myInterpreter.value);
  

Additionally, API calls may be added to the interpreter during creation. Here is the addition of alert() and a url variable:

    var myCode = 'alert(url);';
    var initFunc = function(interpreter, scope) {
      interpreter.setProperty(scope, 'url',
          interpreter.createPrimitive(location.toString()));

      var wrapper = function(text) {
        text = text ? text.toString() : '';
        return interpreter.createPrimitive(alert(text));
      };
      interpreter.setProperty(scope, 'alert',
          interpreter.createNativeFunction(wrapper));
    };
    var myInterpreter = new Interpreter(myCode, initFunc);
  

For more examples, see the initGlobalScope function which creates APIs for Math, Array, Function, and other globals.

Limitations

The version of JavaScript implemented by the interpreter has a few differences from that which executes in a browser:

API
None of the DOM APIs are exposed. That's kind of the point of a sandbox. If you need these, write your own interfaces.
Try
The try/catch and try/finally constructs are not currently supported. Feel free to add them if you need them.
Wat
Some of the more obscure type conversions (e.g. [] + {}) may return different results from JavaScript. Patches are welcome.
Todo
A laundry list of random items that are currently missing but are slowly being worked on:

Dependency

The only dependency is Acorn, a beautifully written JavaScript parser by Marijn Haverbeke. It is included in the JS-Interpreter package.

Compatibility

The limiting factor for browser support is the use of Object.create(null) to create hash objects in both Acorn and JS-Interpreter. This results in the following minimum browser requirements:

Disclaimer

This project is not an official Google product.