Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Isolate execution of JavaScript

One of the limitation of JS that bugs me the most is the poor ability to isolate code's execution.

I want to be able to control the context in which the code is executed, Something that achieve a similar effect to what Script.createContext & Script.runInContext in node.js does (node is using binding to the V8 engine, so i can't emulate their implementation).

Here is the some reason why I want to isolate code execution:

  1. Isolate the code from the global namespace (the window object and the also the DOM) , but I however need to be able reference function call on objects exposed in the context which must be executed synchronous which makes it almost impossible using a WebWorker for isolation.
  2. By isolate the execution of code it would possible also be able to deallocate its definitions when no longer needed (memory management).

I know one may achieve partly isolated execution by loading script into a iframe, this approach is however very heavy and uses a lot memory for a second instance of the DOM which isn't needed for what I'm trying to do.

I need to share constructor definition and also definitions of object which are shared between the isolated containers/contexts which both must run on the main UI thread. Mainly i want to use these isolated containers to host plugins/modules (mini-applications) which each presents and dynamically updates a viewport by calling drawing commands on their own Context2D object.

If these containers are not running on the main UI thread it wold be painfully hard to proxy calls such as ctx.measureText() and ctx.drawImage() would be all useless as image objects can't be created in a Worker.

Does someone know of future specification that would make this possible?

Are there any current (hidden) browser-side APIs that could be used to achieve this?

Would it be better utilize a virtual machine like Goggle's Dart VM and also re-implement my current codebase? My current codebase is slightly above 20 000 lines of code.

Would it be better to re-implement the framework in *

like image 618
Raweden Avatar asked Apr 29 '12 22:04

Raweden


People also ask

Is JavaScript executed line by line?

JavaScript is a single-threaded language, where only one command executes at a time. It has a Synchronous model of execution, where each line is executed line by line, top to bottom.

What is V8 isolate?

An isolate is a concept of an instance in V8. In Blink, isolates and threads are in 1:1 relationship. One isolate is associated with the main thread. One isolate is associated with one worker thread. An exception is a compositor worker where one isolate is shared by multiple compositor workers.

How do I stop JavaScript execution?

Using return to exit a function in javascript Using return is the easiest way to exit a function. You can use return by itself or even return a value.

What is an isolated vm?

isolated-vm is a library for nodejs which gives you access to v8's Isolate interface. This allows you to create JavaScript environments which are completely isolated from each other.


2 Answers

The closest library I've seen for this is Caja.

Basically, in non-strict javascript code, there are many ways to get access to the global object (window in browsers), making true isolation a very hard problem. Caja does some iframing trickery to patch this, but to be honest I'm not exactly sure how it works.

like image 57
Matt Avatar answered Sep 18 '22 20:09

Matt


You can isolate your code from the global namespace with a simple self executing function object:

(function() {
   // all your code goes here
   // nobody outside of your code can reach your top level variables here
   // your top level variables are not on the window object

   // this is a protected, but top level variable
   var x = 3;

   // if you want anything to be global, you can assign it to the window object.
   window.myGlobal = {};

   function myTopLevelFunction(x,y,z) {
       // code here
   }

})();

If you want to have multiple ones of these execution contexts and be able to share between them, then you will have to rendezvous via one publicly known location, either a truly global variable or a property on a known DOM object or something like that. It is relatively common to declare one global namespace object and use properties off that for any access to things you're sharing among modules. I know it isn't completely perfect, but it works. Here's an example of the rendevous using a single global namespace object:

// module AAA
(function() {
   // module AAA code goes here

   // set up global namespace object and whatever references we want to be global
   window.myModuleTop = window.myModuleTop || {};
   myModuleTop.AAA = {};
   myModuleTop.AAA.myFuncA = function() {};

})();


// module BBB
(function() {
   // module BBB code goes here

   // set up global namespace object and whatever references we want to be global
   window.myModuleTop = window.myModuleTop || {};
   myModuleTop.BBB = {};
   myModuleTop.BBB.myFuncB = function() {};

})();
like image 42
jfriend00 Avatar answered Sep 20 '22 20:09

jfriend00