Skip to content
File

Blob: patches/v8/0009-Add-ValueSerializer-SetTreatFunctionsAsHostObjects.patch

4.6 KB
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Kenton Varda <kenton@cloudflare.com>
3Date: Sat, 2 Mar 2024 09:00:18 -0600
4Subject: Add ValueSerializer::SetTreatFunctionsAsHostObjects().
5 
6Previously, ValueSerializer would always refuse to serialize functions. This commit gives the embedder the option to handle them as host objects.
7 
8This is intended for use in an RPC system, where a function can be "serialized" by replacing it with a stub which, when invoked, performs an RPC back to the originating isolate in order to execute the original function there.
9 
10Signed-off-by: James M Snell <jsnell@cloudflare.com>
11 
12diff --git a/include/v8-value-serializer.h b/include/v8-value-serializer.h
13index 596be18adeb3a5a81794aaa44b1d347dec6c0c7d..141f138e08de849e3e02b3b2b346e643b9e40c70 100644
14--- a/include/v8-value-serializer.h
15+++ b/include/v8-value-serializer.h
16@@ -195,6 +195,15 @@ class V8_EXPORT ValueSerializer {
17 */
18 void SetTreatArrayBufferViewsAsHostObjects(bool mode);
19
20+ /**
21+ * Indicate whether to treat Functions as host objects,
22+ * i.e. pass them to Delegate::WriteHostObject. This should not be
23+ * called when no Delegate was passed.
24+ *
25+ * The default is not to treat Functions as host objects.
26+ */
27+ void SetTreatFunctionsAsHostObjects(bool mode);
28+
29 /**
30 * Write raw data in various common formats to the buffer.
31 * Note that integer types are written in base-128 varint format, not with a
32diff --git a/src/api/api.cc b/src/api/api.cc
33index 2c226e1467d952fd80c5356f7993f8af00c5f35d..877765bf5f57a2953aa2d1e0869ae5db12e8b6b1 100644
34--- a/src/api/api.cc
35+++ b/src/api/api.cc
36@@ -3588,6 +3588,10 @@ void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
37 private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
38 }
39
40+void ValueSerializer::SetTreatFunctionsAsHostObjects(bool mode) {
41+ private_->serializer.SetTreatFunctionsAsHostObjects(mode);
42+}
43+
44 Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
45 Local<Value> value) {
46 auto i_isolate = i::Isolate::Current();
47diff --git a/src/objects/value-serializer.cc b/src/objects/value-serializer.cc
48index fc4dc2477d48c97145237e922d3bcba16140c47d..97b7f51664dda24ffb0c94e4033b2eff2ba4daee 100644
49--- a/src/objects/value-serializer.cc
50+++ b/src/objects/value-serializer.cc
51@@ -335,6 +335,10 @@ void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
52 treat_array_buffer_views_as_host_objects_ = mode;
53 }
54
55+void ValueSerializer::SetTreatFunctionsAsHostObjects(bool mode) {
56+ treat_functions_as_host_objects_ = mode;
57+}
58+
59 void ValueSerializer::WriteTag(SerializationTag tag) {
60 uint8_t raw_tag = static_cast<uint8_t>(tag);
61 WriteRawBytes(&raw_tag, sizeof(raw_tag));
62@@ -604,13 +608,17 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(
63
64 // Eliminate callable and exotic objects, which should not be serialized.
65 InstanceType instance_type = receiver->map()->instance_type();
66- if (IsCallable(*receiver) ||
67- (IsSpecialReceiverInstanceType(instance_type) &&
68+ if (IsCallable(*receiver)) {
69+ if (treat_functions_as_host_objects_) {
70+ return WriteHostObject(Cast<JSObject>(receiver));
71+ }
72+ return ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver);
73+ } else if (IsSpecialReceiverInstanceType(instance_type) &&
74 instance_type != JS_SPECIAL_API_OBJECT_TYPE
75 #if V8_ENABLE_WEBASSEMBLY
76 && instance_type != WASM_STRUCT_TYPE && instance_type != WASM_ARRAY_TYPE
77 #endif
78- )) {
79+ ) {
80 return ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver);
81 }
82
83diff --git a/src/objects/value-serializer.h b/src/objects/value-serializer.h
84index 06475f7b9c2a797066f5cfd32b232e5aa55f1f75..ddc5f27a80f93bae209f3fe8731d4df4baa58ead 100644
85--- a/src/objects/value-serializer.h
86+++ b/src/objects/value-serializer.h
87@@ -102,6 +102,15 @@ class ValueSerializer {
88 */
89 void SetTreatArrayBufferViewsAsHostObjects(bool mode);
90
91+ /*
92+ * Indicate whether to treat Functions as host objects,
93+ * i.e. pass them to Delegate::WriteHostObject. This should not be
94+ * called when no Delegate was passed.
95+ *
96+ * The default is not to treat Functions as host objects.
97+ */
98+ void SetTreatFunctionsAsHostObjects(bool mode);
99+
100 private:
101 // Managing allocations of the internal buffer.
102 Maybe<bool> ExpandBuffer(size_t required_capacity);
103@@ -185,6 +194,7 @@ class ValueSerializer {
104 size_t buffer_capacity_ = 0;
105 bool has_custom_host_objects_ = false;
106 bool treat_array_buffer_views_as_host_objects_ = false;
107+ bool treat_functions_as_host_objects_ = false;
108 bool out_of_memory_ = false;
109 Zone zone_;
110 uint32_t version_;