package otto import ( "fmt" ) type _clone struct { runtime *_runtime _object map[*_object]*_object _objectStash map[*_objectStash]*_objectStash _dclStash map[*_dclStash]*_dclStash _fnStash map[*_fnStash]*_fnStash } func (in *_runtime) clone() *_runtime { in.lck.Lock() defer in.lck.Unlock() out := &_runtime{} clone := _clone{ runtime: out, _object: make(map[*_object]*_object), _objectStash: make(map[*_objectStash]*_objectStash), _dclStash: make(map[*_dclStash]*_dclStash), _fnStash: make(map[*_fnStash]*_fnStash), } globalObject := clone.object(in.globalObject) out.globalStash = out.newObjectStash(globalObject, nil) out.globalObject = globalObject out.global = _global{ clone.object(in.global.Object), clone.object(in.global.Function), clone.object(in.global.Array), clone.object(in.global.String), clone.object(in.global.Boolean), clone.object(in.global.Number), clone.object(in.global.Math), clone.object(in.global.Date), clone.object(in.global.RegExp), clone.object(in.global.Error), clone.object(in.global.EvalError), clone.object(in.global.TypeError), clone.object(in.global.RangeError), clone.object(in.global.ReferenceError), clone.object(in.global.SyntaxError), clone.object(in.global.URIError), clone.object(in.global.JSON), clone.object(in.global.ObjectPrototype), clone.object(in.global.FunctionPrototype), clone.object(in.global.ArrayPrototype), clone.object(in.global.StringPrototype), clone.object(in.global.BooleanPrototype), clone.object(in.global.NumberPrototype), clone.object(in.global.DatePrototype), clone.object(in.global.RegExpPrototype), clone.object(in.global.ErrorPrototype), clone.object(in.global.EvalErrorPrototype), clone.object(in.global.TypeErrorPrototype), clone.object(in.global.RangeErrorPrototype), clone.object(in.global.ReferenceErrorPrototype), clone.object(in.global.SyntaxErrorPrototype), clone.object(in.global.URIErrorPrototype), } out.eval = out.globalObject.property["eval"].value.(Value).value.(*_object) out.globalObject.prototype = out.global.ObjectPrototype // Not sure if this is necessary, but give some help to the GC clone.runtime = nil clone._object = nil clone._objectStash = nil clone._dclStash = nil clone._fnStash = nil return out } func (clone *_clone) object(in *_object) *_object { if out, exists := clone._object[in]; exists { return out } out := &_object{} clone._object[in] = out return in.objectClass.clone(in, out, clone) } func (clone *_clone) dclStash(in *_dclStash) (*_dclStash, bool) { if out, exists := clone._dclStash[in]; exists { return out, true } out := &_dclStash{} clone._dclStash[in] = out return out, false } func (clone *_clone) objectStash(in *_objectStash) (*_objectStash, bool) { if out, exists := clone._objectStash[in]; exists { return out, true } out := &_objectStash{} clone._objectStash[in] = out return out, false } func (clone *_clone) fnStash(in *_fnStash) (*_fnStash, bool) { if out, exists := clone._fnStash[in]; exists { return out, true } out := &_fnStash{} clone._fnStash[in] = out return out, false } func (clone *_clone) value(in Value) Value { out := in switch value := in.value.(type) { case *_object: out.value = clone.object(value) } return out } func (clone *_clone) valueArray(in []Value) []Value { out := make([]Value, len(in)) for index, value := range in { out[index] = clone.value(value) } return out } func (clone *_clone) stash(in _stash) _stash { if in == nil { return nil } return in.clone(clone) } func (clone *_clone) property(in _property) _property { out := in switch value := in.value.(type) { case Value: out.value = clone.value(value) case _propertyGetSet: p := _propertyGetSet{} if value[0] != nil { p[0] = clone.object(value[0]) } if value[1] != nil { p[1] = clone.object(value[1]) } out.value = p default: panic(fmt.Errorf("in.value.(Value) != true; in.value is %T", in.value)) } return out } func (clone *_clone) dclProperty(in _dclProperty) _dclProperty { out := in out.value = clone.value(in.value) return out }