views:

92

answers:

2

I am working on a migration platform to migrate web applications from a device to another. I am extending it to add the support for preserving JavaScript state. My main task is to create a file representing the current state of the executing application, to transmit it to another device and to reload the state in the destination device.

The basic solution I adopted is to navigate the window object and to save all its descendant properties using JSON as base format for exportation and extending it to implement some features:

  • preserving object reference, even if cyclic (dojox.json.ref library)
  • support for timers
  • Date
  • non-numericproperties of arrays
  • reference to DOM elements

The most important task I need to solve now is exportation of closures. At this moment I didn't know how to implement this feature. I read about the internal EcmaScript property [[scope]] containing the scope chain of a function, a list-like object composed by all the nested activation context of the function. Unfortunately it is not accessible by JavaScript. Anyone know if there is a way to directly access the [[scope]] property? Or another way to preserve the state of a closure?

+2  A: 

This sounds like an impossible feat as you would need access to the references stored in each variable.

The best solution would probably be to first refactor your code into storing state on an available object - that way you could easily use JSON.stringify/parse to save/restore it.

So go from

var myFuncWithScope = (function() {
    var variable = 0;
    return function() {
        return variable++;
    }
})(); 

var serializedState = .... // no can do

to

var state = {
    myScope = {
        variable: 0
    }
};

var myFuncWithoutScope = function(){
    return state.myScope.variable++;
}

var serializedState = JSON.stringify(state);
Sean Kinsey
It is not clear what you mean with "refactor your code into storing state on an available object" but I think that it is what I'm actually doing when I store all `window` properties in a map and pass that map to my modified version of JSON. What I was asking in this post was a solution to the problem: "How can I serialize a closure and restore it back into another device?"
Uccio
My point was that you cannot serialize/deserialize a scope. But if all state is stored *outside* the closure, as properties, then you have no need to store the closure as it can just be recreated by script.
Sean Kinsey
Very interesting solution but I think it is not applicable to my case and anyway code refactoring is far beyond the scope of my work.
Uccio
+2  A: 

From where are you executing? If you are a native app or web browser extension you may have some hope, via internal access to whichever scripting engine it's using. But from a script in web content, there is no hope.

[[Scope]] is one ECMAScript internal property that you cannot access or preserve from inside the interpreter, but far from the only one; almost all of the [[...]] properties are not accessible. Function code references, prototypes, properties, enumerability, owner context, listeners, everything to do with host objects (such as DOM nodes)... there are infinitely many ways to fail.

You can't preserve or migrate web applications without requiring them to follow some strict rules to avoid all but the most basic JS features.

bobince
The platform has a migration proxy between the server and the client, that intercepts the client page requests and responds with a modified web page with some JavaScript. So I am executing from a script in web content. I know it would be hard to migrate entirely the JavaScript state , but I'm a trying to solve the subproblems one by one. I wanted to use pure JavaScript because I wanted to make the migration platform work with every browser. But, if necessary, I could use some browser dependent code. e.g. I was wondering how FireBug keep tracks of scope chains in the stack trace...
Uccio
Firebug is a browser extension, so has access to internal interpreter state you won't be able to see from web content. It is not just hard to fully migrate state, it is explicitly impossible. There are some objects that have external state so simply cannot be cloned/serialised/restored even with native-level access, never mind the limited access you get from web content.
bobince