bool WriteStructuredClone(JSContext* aCx, JS::Handle<JS::Value> aSource, JSAutoStructuredCloneBuffer& aBuffer, StructuredCloneClosure& aClosure) { return aBuffer.write(aCx, aSource, &gCallbacks, &aClosure); }
static bool Serialize(JSContext *cx, unsigned argc, jsval *vp) { CallArgs args = CallArgsFromVp(argc, vp); JSAutoStructuredCloneBuffer clonebuf; if (!clonebuf.write(cx, args.get(0), args.get(1))) return false; RootedObject obj(cx, CloneBufferObject::Create(cx, &clonebuf)); if (!obj) return false; args.rval().setObject(*obj); return true; }
static jobject CloneInstance(JNIEnv* env, jobject instance) { NativeJSContainer* const container = FromInstance(env, instance); if (!container || !container->EnsureObject(env)) { return nullptr; } JSContext* const cx = container->mThreadContext; JS::RootedObject object(cx, container->mJSObject); MOZ_ASSERT(object); JSAutoStructuredCloneBuffer buffer; if (!buffer.write(cx, JS::RootedValue(cx, JS::ObjectValue(*object)))) { AndroidBridge::ThrowException(env, "java/lang/UnsupportedOperationException", "Cannot serialize object"); return nullptr; } return CreateInstance(env, new NativeJSContainer(cx, Move(buffer))); }
void ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage, const Optional<Sequence<JS::Value>>& aTransferable, ErrorResult& aRv) { WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(workerPrivate); workerPrivate->AssertIsOnWorkerThread(); JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue()); if (aTransferable.WasPassed()) { const Sequence<JS::Value>& realTransferable = aTransferable.Value(); JS::HandleValueArray elements = JS::HandleValueArray::fromMarkedLocation(realTransferable.Length(), realTransferable.Elements()); JSObject* array = JS_NewArrayObject(aCx, elements); if (!array) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } transferable.setObject(*array); } const JSStructuredCloneCallbacks* callbacks = WorkerStructuredCloneCallbacks(false); WorkerStructuredCloneClosure closure; JSAutoStructuredCloneBuffer buffer; if (!buffer.write(aCx, aMessage, transferable, callbacks, &closure)) { aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); return; } nsRefPtr<ServiceWorkerClientPostMessageRunnable> runnable = new ServiceWorkerClientPostMessageRunnable(mWindowId, Move(buffer), closure); nsresult rv = NS_DispatchToMainThread(runnable); if (NS_FAILED(rv)) { aRv.Throw(NS_ERROR_FAILURE); } }
DataStoreAddRunnable(WorkerPrivate* aWorkerPrivate, const nsMainThreadPtrHandle<DataStore>& aBackingStore, Promise* aWorkerPromise, JSContext* aCx, JS::Handle<JS::Value> aObj, const Optional<StringOrUnsignedLong>& aId, const nsAString& aRevisionId, ErrorResult& aRv) : DataStoreProxyRunnable(aWorkerPrivate, aBackingStore, aWorkerPromise) , mId(aId) , mRevisionId(aRevisionId) , mRv(aRv) { MOZ_ASSERT(aWorkerPrivate); aWorkerPrivate->AssertIsOnWorkerThread(); // This needs to be structured cloned while it's still on the worker thread. if (!mObjBuffer.write(aCx, aObj)) { JS_ClearPendingException(aCx); mRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR); } }
/* * General-purpose structured-cloning utility for cases where the structured * clone buffer is only used in stack-scope (that is to say, the buffer does * not escape from this function). The stack-scoping allows us to pass * references to various JSObjects directly in certain situations without * worrying about lifetime issues. * * This function assumes that |cx| is already entered the compartment we want * to clone to, and that |val| may not be same-compartment with cx. When the * function returns, |val| is set to the result of the clone. */ bool StackScopedClone(JSContext *cx, StackScopedCloneOptions &options, MutableHandleValue val) { JSAutoStructuredCloneBuffer buffer; StackScopedCloneData data(cx, &options); { // For parsing val we have to enter its compartment. // (unless it's a primitive) Maybe<JSAutoCompartment> ac; if (val.isObject()) { ac.construct(cx, &val.toObject()); } else if (val.isString() && !JS_WrapValue(cx, val)) { return false; } if (!buffer.write(cx, val, &gStackScopedCloneCallbacks, &data)) return false; } // Now recreate the clones in the target compartment. return buffer.read(cx, val, &gStackScopedCloneCallbacks, &data); }