static RawObject CloneObject(JSContext *cx, HandleObject srcObj, CloneMemory &clonedObjects) { CloneMemory::AddPtr p = clonedObjects.lookupForAdd(srcObj.get()); if (p) return p->value; RootedObject clone(cx); if (srcObj->isFunction()) { RootedFunction fun(cx, srcObj->toFunction()); clone = CloneFunctionObject(cx, fun, cx->global(), fun->getAllocKind()); } else if (srcObj->isRegExp()) { RegExpObject &reobj = srcObj->asRegExp(); RootedAtom source(cx, reobj.getSource()); clone = RegExpObject::createNoStatics(cx, source, reobj.getFlags(), NULL); } else if (srcObj->isDate()) { clone = JS_NewDateObjectMsec(cx, srcObj->getDateUTCTime().toNumber()); } else if (srcObj->isBoolean()) { clone = BooleanObject::create(cx, srcObj->asBoolean().unbox()); } else if (srcObj->isNumber()) { clone = NumberObject::create(cx, srcObj->asNumber().unbox()); } else if (srcObj->isString()) { Rooted<JSStableString*> str(cx, srcObj->asString().unbox()->ensureStable(cx)); if (!str) return NULL; str = js_NewStringCopyN(cx, str->chars().get(), str->length())->ensureStable(cx); if (!str) return NULL; clone = StringObject::create(cx, str); } else if (srcObj->isDenseArray()) { return CloneDenseArray(cx, srcObj, clonedObjects); } else { if (srcObj->isArray()) { clone = NewDenseEmptyArray(cx); } else { JS_ASSERT(srcObj->isNative()); clone = NewObjectWithClassProto(cx, srcObj->getClass(), NULL, cx->global(), srcObj->getAllocKind()); } } if (!clone || !clonedObjects.relookupOrAdd(p, srcObj.get(), clone.get()) || !CloneProperties(cx, srcObj, clone, clonedObjects)) { return NULL; } return clone; }