Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2020-06-06 17:11:31 +0300
committerAnna Henningsen <anna@addaleax.net>2020-06-14 15:53:39 +0300
commit9129cf21ab51432675521ea158191ae3f866cafb (patch)
treea495ade59782e28a4ba94ddee085349e083cdd09 /src/node_messaging.h
parent8ead0211d7ee534015a10cc99c01a14cc38cbd3a (diff)
worker: allow passing JS wrapper objects via postMessage
Enable JS wrapper objects to be used as transferable or cloneable objects in `postMessage()` calls, by having them extend a C++-backed class. This requires a few internal changes: - This commit adds the possibility for transferred objects to read/write JS values at the end of the serialization/deserialization phases. - This commit adds the possibility for transferred objects to list sub-transferables, e.g. typically the public JS wrapper class would list its C++ handle in there. - This commit adds usage of `BaseObject` in a few more places, because now during deserialization weakly held objects can also be involved, in addition to `MessagePort`s. PR-URL: https://github.com/nodejs/node/pull/33772 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Diffstat (limited to 'src/node_messaging.h')
-rw-r--r--src/node_messaging.h52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/node_messaging.h b/src/node_messaging.h
index 649ee201045..378468b6f44 100644
--- a/src/node_messaging.h
+++ b/src/node_messaging.h
@@ -30,6 +30,12 @@ class TransferData : public MemoryRetainer {
Environment* env,
v8::Local<v8::Context> context,
std::unique_ptr<TransferData> self) = 0;
+ // FinalizeTransferWrite() is the counterpart to
+ // BaseObject::FinalizeTransferRead(). It is called right after the transfer
+ // data was created, and defaults to doing nothing. After this function,
+ // this object should not hold any more Isolate-specific data.
+ virtual v8::Maybe<bool> FinalizeTransferWrite(
+ v8::Local<v8::Context> context, v8::ValueSerializer* serializer);
};
// Represents a single communication message.
@@ -239,6 +245,52 @@ class MessagePort : public HandleWrap {
friend class MessagePortData;
};
+// Provide a base class from which JS classes that should be transferable or
+// cloneable by postMesssage() can inherit.
+// See e.g. FileHandle in internal/fs/promises.js for an example.
+class JSTransferable : public BaseObject {
+ public:
+ JSTransferable(Environment* env, v8::Local<v8::Object> obj);
+ static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
+
+ TransferMode GetTransferMode() const override;
+ std::unique_ptr<TransferData> TransferForMessaging() override;
+ std::unique_ptr<TransferData> CloneForMessaging() const override;
+ v8::Maybe<std::vector<BaseObjectPtr<BaseObject>>>
+ NestedTransferables() const override;
+ v8::Maybe<bool> FinalizeTransferRead(
+ v8::Local<v8::Context> context,
+ v8::ValueDeserializer* deserializer) override;
+
+ SET_NO_MEMORY_INFO()
+ SET_MEMORY_INFO_NAME(JSTransferable)
+ SET_SELF_SIZE(JSTransferable)
+
+ private:
+ std::unique_ptr<TransferData> TransferOrClone(TransferMode mode) const;
+
+ class Data : public TransferData {
+ public:
+ Data(std::string&& deserialize_info, v8::Global<v8::Value>&& data);
+
+ BaseObjectPtr<BaseObject> Deserialize(
+ Environment* env,
+ v8::Local<v8::Context> context,
+ std::unique_ptr<TransferData> self) override;
+ v8::Maybe<bool> FinalizeTransferWrite(
+ v8::Local<v8::Context> context,
+ v8::ValueSerializer* serializer) override;
+
+ SET_NO_MEMORY_INFO()
+ SET_MEMORY_INFO_NAME(JSTransferableTransferData)
+ SET_SELF_SIZE(Data)
+
+ private:
+ std::string deserialize_info_;
+ v8::Global<v8::Value> data_;
+ };
+};
+
v8::Local<v8::FunctionTemplate> GetMessagePortConstructorTemplate(
Environment* env);