Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way serialize *otto.Otto and save it to disk? #133

Open
jclohmann opened this issue Aug 21, 2015 · 3 comments
Open

Is there a way serialize *otto.Otto and save it to disk? #133

jclohmann opened this issue Aug 21, 2015 · 3 comments

Comments

@jclohmann
Copy link

Hi!
Is there a way to serialize the Otto-object (or some other context-containing-object)?
I would like to save javascripts this (with all dynamicly added fields) to disk and be able to load it after a restart.

Simply pushing it into a gob.Encoder (or json.Encoder) seems not to work :-)

@deoxxa
Copy link
Collaborator

deoxxa commented Dec 5, 2015

I feel like there are two "levels" for this kind of feature.

  1. being able to serialise the global state of the vm - things like defined functions, variables, etc. For this, _runtime.clone would probably be a good place to start investigating.
  2. being able to serialise the current execution context of the vm - basically the entire call stack. This would probably be really tricky, especially if there are native functions on the stack.

@darkliquid
Copy link
Contributor

Agreed. Some kind of global state serialisation based on clone seems a good area to investigate and could be useful.

I think point 2 might be doable if you make some assumptions:

  • the serialised context will be loaded by the same program that generated it
  • native functions aren't serialised, just pointers to them
  • pointers to functions have to be public, defined functions - no anonymous/private/dynamic ones

If all the assumptions there are true, I would guess you could have a special serialisation format for native functions that annotates the full package path, object references, etc to be able to find and replumb in the function call. However, thats not trivial by any stretch of the imagination. I'm not entirely convinced of the utility of this though, it seems like a lot of work for some very limited use-cases.

Arguably it would be better to write a book-keeping wrapper around your runtime that tracks native functions being attached and has it's own serialisation system that works in tandem with the stuff in point 1 to rebuild your execution context, as typically the functiosn you want to expose are going to be from all over the place and otto can't be expected to have the required domain knowledge to work in a generic sense.

@alexandru-eftimie
Copy link

I use a simple-ish way to export and save most of what I actually need.

var $exclude = "$exclude,console,..."// replace ... with other functions to ignore
$exclude = $exclude.split(",")
function exportGlobal(src) {

    var dst = {}
    var keys = Object.keys(src)
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i]

        // skip exluded keys
        if ($exclude.indexOf(key) != -1) {
            continue;
        }

        var element = src[key];
        if (typeof element == "function") {
            dst[key] = "func://" + element.toString()
        } else {
            dst[key] = element
        }
    }
    return JSON.stringify(dst)
}
function importGlobal(dst, src) {

    var keys = Object.keys(src)

    for (var i = 0; i < keys.length; i++) {
        var key = keys[i]

        // skip exluded keys
        if ($exclude.indexOf(key) != -1) {
            continue;
        }

        var element = src[key];
        if (typeof element == "string" && element.substring(0, 7) == "func://") {
            eval("dst[key] = " + element.substring(7))
        } else {
            dst[key] = element
        }
    }
}

And I run on save:

o.Run("exportGlobal(this)")

On load:

o.Run("importGlobal(this, " + old + ")")

It saves global functions but not nested ones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants