克隆整个JavaScript ScriptEngine [英] Clone Entire JavaScript ScriptEngine

查看:125
本文介绍了克隆整个JavaScript ScriptEngine的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要以某种方式深度克隆我的 ScriptEngine 对象。

I need to somehow deep clone the entire set of bindings of my ScriptEngine object.


  • 到目前为止,我已尝试使用 Cloner库来克隆整个Bindings结构。如果它有用,那将是很好的,因为它可以确保精确的副本,包括私有变量。但是这会导致jvm堆损坏(jvm只是崩溃,退出代码为-1073740940)。有时它不会崩溃,但会发生奇怪的事情,例如 System.out.println()停止工作......

  • I have tried so far the Cloner library to clone the entire Bindings structure. This would be great if it worked because it would have ensured a precise copy, including private variables. But this leads to jvm heap corruption (the jvm just crashes with exit code -1073740940). Sometimes it doesn't crash but weird things happen, like the System.out.println() stops working as it should...

我还研究了在ScriptEngine中使用js代码克隆对象,这样我就可以将它们作为NativeObjects获取并在一些java地图中管理它们。但是我发现的所有克隆方法都存在缺陷。我想要一个精确的对象快照。例如,如果两个对象a和b中的每一个都包含引用相同对象c的字段(例如a.fa和b.fb),则使用 jQuery.extend()克隆 (例如)克隆的a和b的字段 a.fa b.fb 将引用不同的克隆c,而不是引用一个相同的克隆。还有许多其他边缘问题。

I have also looked into cloning the objects using js code inside the ScriptEngine, so that I can get those as NativeObjects and manage them in some java maps. But all cloning methods which I found have flaws. I want a precise snapshot of the objects. For instance if each of two objects a and b contain fields (say a.fa and b.fb) which reference the same object c, when cloned using jQuery.extend() (for instance) the fields a.fa and b.fb of the cloned a and b will reference different clones of c, instead of referencing one same clone. And many other edge issues.

我还尝试使用Cloner克隆整个ScriptEngine(不仅仅是绑定),我还尝试使用Rhino的js引擎和克隆整个范围(而不是Bundeled ScriptEngine包装器)。但堆腐败问题仍然存在。

I also tried to clone the entire ScriptEngine using Cloner (not only the bindings), and I also tried using Rhino's js engine and clone the entire scope (instead of the bundeled ScriptEngine wrapper). But the heap corruption issue persists.

我需要这个,因为我必须能够将整个ScriptEngine绑定的值恢复到之前的某个点。我需要对绑定进行精确的快照。

I need this because I must be able to restore the values of the entire ScriptEngine bindings to some previous point. I need to make precise snapshots of the bindings.

该应用程序是我的博士研究项目的一部分,该项目包括运行状态机和节点(在java中实现),其中包含js附加代码。 js代码由最终用户输入,并且在运行时被逐出。当无法通过路径到达最终状态时,算法会向后执行步骤,尝试查找备用路径。在每一步向后,它必须撤消js引擎绑定中可能发生的任何更改。

The application is part of my doctoral research project which consists of running state machines with nodes (implemented in java) which have js code attached. The js code is typed in by the end user and it is being evaled at runtime. When final state can't be reached through a path, the algorithm makes steps backwards, trying to find alternative paths. On each step backward it must undo any changes that might have occurred in the js engine bindings.

所有全局变量名称在js evaling之前是已知的,并且是对象(用户在节点的代码中键入,然后将其组织(在java中)到具有某些名称模式的js对象中)。但是它们的内容可以是任何东西,因为它是由用户js代码控制的。

All the global variables names are known before js eval-ing, and are objects (the user types in code for the nodes and this is then organized (within java) into js objects with certain name patterns). But their content can be anything because that is controlled by the user js code.

所以我想我现在唯一的解决办法是使用js代码克隆js对象。

So I guess my only sollution now is to clone js object using js code.

推荐答案

除了边缘情况之外,jQuery.extend可以按照你提到的方式使用。 a b 并且他们的克隆都会引用同一个对象 c

Aside from "edge cases", jQuery.extend can be used in the way you mention. a b and their clones will all reference the same object c.

var c = { f:'see' };
var a = { fa: c };
var b = { fb: c };
var cloneA = $.extend({}, a);
var cloneB = $.extend({}, b);
console.log(a.fa === b.fb, cloneA.fa === cloneB.fb, a.fa === cloneB.fb);
// true true true

但似乎你想要克隆所有对象(包括 c ),同时跟踪对象的关系。为此,最好使用对象关系表。

But it seems like you want to clone all the objects (including c) while keeping track of the objects' relationships. For this, it may be best to use object relation tables.

我通过嵌套的javascript对象和JSON看到了很多,因为人们往往会忘记JSON纯粹是一个文本格式。除了单个文本字符串 instanceof String 之外,JSON文件中没有实际的javascript对象。 javascript中没有豆类或泡菜或任何防腐剂重的食物。

I see this a lot with nested javascript objects and JSON because people tend to forget that JSON is purely a text format. There are no actual javascript objects in a JSON file except for a single string of text instanceof String. There are no beans or pickles or any preservative-heavy foods in javascript.

在对象关系表中,每个表格只是一个平面对象的数组只有原始值属性和指向表(或另一个表)中其他对象的指针(不是引用)。指针可以只是目标对象的索引。

In an object relation table, each 'table' is just an array of "flat" objects with only primitive valued properties and pointers (not references) to other objects in the table (or in another table). The pointer can just be the index of the target object.

因此上述对象关系的JSON版本可能类似于

So a JSON version of the above object relationship might look something like

{
    "table-1":[
        { "a": { "fa":["table-2",0] } },
        { "b": { "fb":["table-2",0] } }
    ],
    "table-2":[
        { "c": { "name":"see" } },
        { "d": { "name":"dee" } },
        { "e": { "name":"eh.."} }
    ]
}

解析器可能看起来像

var tables = JSON.parse(jsonString);
for(var key in tables){
    var table = tables[key];
    for(var i = 0; i < table.length; i++){
        var name = Object.keys(table[i])
        var obj = table[i][name];
        for(var key2 in obj){
            if(obj[key2] instanceof Array && obj[key2][0] in tables){
                var refTable = obj[key2][0];
                var refID    = obj[key2][1];
                var refObj   = tables[refTable][refID];
                var refKey   = Object.keys(refObj)[0];
                obj[key2] = refObj[refKey];
            }
        }
        this[name] = obj;
    }
}

console.log(a.fa === b.fb, b.fb === c);
// true true

我意识到对象关系映射有它的垮台,但拍摄快照脚本引擎听起来有点疯狂。特别是因为你的目的是能够回忆起前面的每一步,因为那时你需要为每一步创建一个新的快照...这将很快占用大量的磁盘空间..除非你只是跟踪快照每个步骤之间的差异,就像一个git repo。实现一个看似简单的撤销方法听起来真是太多了。

I realize object relationship mapping has it's downfalls, but taking snapshots of the scripting engine does sound a bit crazy. Especially since your intention is to be able to recall each previous step, because then you need a new snapshot for every step... that will very quickly take up shit ton of disk space.. unless you're just keeping track of the snapshot diffs between each step, like a git repo. That sounds like an awful lot of work to implement a seemingly simple "undo" method.

该死的......想一想,为什么不把每一步存储在一个历史文件?然后,如果您需要后退,只需截断上一步中的历史记录文件,然后在新环境中再次运行每个步骤。

Damn.. come to think of it, why not just store each step in a history file? Then if you need to step back, just truncate the history file at the previous step, and run each step over again in a fresh environment.

不确定使用java有多么实用(性能明智)。 Nodejs(现在存在)比任何java脚本引擎都要快。事实上,从现在开始我就把它称为ECMAscript。抱歉,这只是咆哮,只是那个

Not sure how practical that would be (performance wise) using java. Nodejs (as it exists today) is faster than any java scripting engine will ever be. In fact, I'm just gonna call it ECMAscript from now on. Sorry bout the rant, its just that

Java很慢,但你已经知道了。

因为它很容易显示,就像它一样快。

Java is slow, but you already know.
Because it readily shows, that's as fast as it goes.

这篇关于克隆整个JavaScript ScriptEngine的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆