-
Notifications
You must be signed in to change notification settings - Fork 303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSRPC: Support "serializing" functions by turning them into stubs #1756
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
96afb24
JSRPC: Don't allow serializing application class instances.
kentonv 4079859
JSRPC: Improve the error message when failing to serialize host objects.
kentonv e5601d9
JSRPC: Serialize functions as RPC stubs.
kentonv 35d4886
JSRPC: Refactor: Pull callImpl() out as standalone function.
kentonv 05a19ec
JSRPC: Refactor: Don't template callImpl().
kentonv 012ac44
JSRPC: Refactor: Factor out code to create JsRpcPromise.
kentonv 6c05025
JSRPC: Monkeypatch assert.rejects to not be confused by callable then…
kentonv 8d0b411
JSRPC: Change internal_thenable.js isValidThenable() to accept callab…
kentonv 16fa442
JSRPC: Make JsRpcStub and JsRpcPromise callable.
kentonv ca221dd
JSRPC: Allow accessing properties of functions.
kentonv 3cdedb6
JSRPC: Make sure JsRpcPromise and JsRpcProperty aren't treated as fun…
kentonv 0bb6c64
JSRPC: Add missing visitForGc().
kentonv 9709be1
JSRPC: Implement visitForMemoryInfo() for RPC types.
kentonv cfd3d79
JSRPC: Test that objects with null prototypes are not accessible.
kentonv File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
patches/v8/0015-Add-ValueSerializer-SetTreatFunctionsAsHostObjects.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Kenton Varda <[email protected]> | ||
Date: Sat, 2 Mar 2024 09:00:18 -0600 | ||
Subject: Add ValueSerializer::SetTreatFunctionsAsHostObjects(). | ||
|
||
Previously, ValueSerializer would always refuse to serialize functions. This commit gives the embedder the option to handle them as host objects. | ||
|
||
This 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. | ||
|
||
diff --git a/include/v8-value-serializer.h b/include/v8-value-serializer.h | ||
index 596be18adeb3a5a81794aaa44b1d347dec6c0c7d..141f138e08de849e3e02b3b2b346e643b9e40c70 100644 | ||
--- a/include/v8-value-serializer.h | ||
+++ b/include/v8-value-serializer.h | ||
@@ -195,6 +195,15 @@ class V8_EXPORT ValueSerializer { | ||
*/ | ||
void SetTreatArrayBufferViewsAsHostObjects(bool mode); | ||
|
||
+ /** | ||
+ * Indicate whether to treat Functions as host objects, | ||
+ * i.e. pass them to Delegate::WriteHostObject. This should not be | ||
+ * called when no Delegate was passed. | ||
+ * | ||
+ * The default is not to treat Functions as host objects. | ||
+ */ | ||
+ void SetTreatFunctionsAsHostObjects(bool mode); | ||
+ | ||
/** | ||
* Write raw data in various common formats to the buffer. | ||
* Note that integer types are written in base-128 varint format, not with a | ||
diff --git a/src/api/api.cc b/src/api/api.cc | ||
index 336aaf5512f743d1202d503e388d2ac9ef5a9377..d736a92e87c758a82247af6623d5a706c646c978 100644 | ||
--- a/src/api/api.cc | ||
+++ b/src/api/api.cc | ||
@@ -3577,6 +3577,10 @@ void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) { | ||
private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode); | ||
} | ||
|
||
+void ValueSerializer::SetTreatFunctionsAsHostObjects(bool mode) { | ||
+ private_->serializer.SetTreatFunctionsAsHostObjects(mode); | ||
+} | ||
+ | ||
Maybe<bool> ValueSerializer::WriteValue(Local<Context> context, | ||
Local<Value> value) { | ||
auto i_isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); | ||
diff --git a/src/objects/value-serializer.cc b/src/objects/value-serializer.cc | ||
index f0b1956253fe603ad6da30a41fb923078ef6bd78..23eff3120d5b20ce4ac1ec8d3700e82a49150308 100644 | ||
--- a/src/objects/value-serializer.cc | ||
+++ b/src/objects/value-serializer.cc | ||
@@ -304,6 +304,10 @@ void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) { | ||
treat_array_buffer_views_as_host_objects_ = mode; | ||
} | ||
|
||
+void ValueSerializer::SetTreatFunctionsAsHostObjects(bool mode) { | ||
+ treat_functions_as_host_objects_ = mode; | ||
+} | ||
+ | ||
void ValueSerializer::WriteTag(SerializationTag tag) { | ||
uint8_t raw_tag = static_cast<uint8_t>(tag); | ||
WriteRawBytes(&raw_tag, sizeof(raw_tag)); | ||
@@ -572,8 +576,13 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { | ||
|
||
// Eliminate callable and exotic objects, which should not be serialized. | ||
InstanceType instance_type = receiver->map()->instance_type(); | ||
- if (IsCallable(*receiver) || (IsSpecialReceiverInstanceType(instance_type) && | ||
- instance_type != JS_SPECIAL_API_OBJECT_TYPE)) { | ||
+ if (IsCallable(*receiver)) { | ||
+ if (treat_functions_as_host_objects_) { | ||
+ return WriteHostObject(Handle<JSObject>::cast(receiver)); | ||
+ } | ||
+ return ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver); | ||
+ } else if (IsSpecialReceiverInstanceType(instance_type) && | ||
+ instance_type != JS_SPECIAL_API_OBJECT_TYPE) { | ||
return ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver); | ||
} | ||
|
||
diff --git a/src/objects/value-serializer.h b/src/objects/value-serializer.h | ||
index 4747119155007e1fa0075440fefa1dfee036c48a..68be2829f36633a386f54668ce9147267c377272 100644 | ||
--- a/src/objects/value-serializer.h | ||
+++ b/src/objects/value-serializer.h | ||
@@ -102,6 +102,15 @@ class ValueSerializer { | ||
*/ | ||
void SetTreatArrayBufferViewsAsHostObjects(bool mode); | ||
|
||
+ /* | ||
+ * Indicate whether to treat Functions as host objects, | ||
+ * i.e. pass them to Delegate::WriteHostObject. This should not be | ||
+ * called when no Delegate was passed. | ||
+ * | ||
+ * The default is not to treat Functions as host objects. | ||
+ */ | ||
+ void SetTreatFunctionsAsHostObjects(bool mode); | ||
+ | ||
private: | ||
// Managing allocations of the internal buffer. | ||
Maybe<bool> ExpandBuffer(size_t required_capacity); | ||
@@ -181,6 +190,7 @@ class ValueSerializer { | ||
size_t buffer_capacity_ = 0; | ||
bool has_custom_host_objects_ = false; | ||
bool treat_array_buffer_views_as_host_objects_ = false; | ||
+ bool treat_functions_as_host_objects_ = false; | ||
bool out_of_memory_ = false; | ||
Zone zone_; | ||
uint32_t version_; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't tell if there was a specific reason for the "not a function" check here. If so, I can remove this commit and keep my ugly monkey-patch instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at it again refreshed my memory, this bit is taken directly from the polyfill that deno is using (https://github.com/denoland/deno/blob/main/ext/node/polyfills/assert.ts#L864) ... looking at it I'm not entirely sure what the intent originally was but I think it's fine to fix this up.