Skip to content

Commit 4b61f10

Browse files
legendecasRafaelGSS
authored andcommitted
deps: V8: cherry-pick e3df60f3f5ab
Original commit message: [objects] allow host defined serializer of JSError Allow host defined serializer and deserializer of JSError in ValueSerializer API. This allows hosts that implement DOMException in JS to support `Error.isError` proposal and `structuredClone`. Refs: #58691 Change-Id: I022821c9abd659970c4d449b3c69c5fb54d0618a Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6637876 Reviewed-by: Camillo Bruni <[email protected]> Commit-Queue: Chengzhong Wu <[email protected]> Cr-Commit-Position: refs/heads/main@{#100894} Refs: v8/v8@e3df60f PR-URL: #58691 Fixes: #56497 Refs: #58138 Reviewed-By: Jason Zhang <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Rafael Gonzaga <[email protected]> Reviewed-By: Ethan Arrowood <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 96c78d7 commit 4b61f10

File tree

3 files changed

+75
-3
lines changed

3 files changed

+75
-3
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
# Reset this number to 0 on major V8 upgrades.
4040
# Increment by one for each non-official patch applied to deps/v8.
41-
'v8_embedder_string': '-node.17',
41+
'v8_embedder_string': '-node.18',
4242

4343
##### V8 defaults for Node.js #####
4444

deps/v8/src/objects/value-serializer.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,17 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(
649649
case JS_DATA_VIEW_TYPE:
650650
case JS_RAB_GSAB_DATA_VIEW_TYPE:
651651
return WriteJSArrayBufferView(Cast<JSArrayBufferView>(*receiver));
652-
case JS_ERROR_TYPE:
653-
return WriteJSError(Cast<JSObject>(receiver));
652+
case JS_ERROR_TYPE: {
653+
DirectHandle<JSObject> js_error = Cast<JSObject>(receiver);
654+
Maybe<bool> is_host_object = IsHostObject(js_error);
655+
if (is_host_object.IsNothing()) {
656+
return is_host_object;
657+
}
658+
if (is_host_object.FromJust()) {
659+
return WriteHostObject(js_error);
660+
}
661+
return WriteJSError(js_error);
662+
}
654663
case JS_SHARED_ARRAY_TYPE:
655664
return WriteJSSharedArray(Cast<JSSharedArray>(receiver));
656665
case JS_SHARED_STRUCT_TYPE:

deps/v8/test/unittests/objects/value-serializer-unittest.cc

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3141,6 +3141,69 @@ TEST_F(ValueSerializerTestWithHostObject, RoundTripHostJSObject) {
31413141
ExpectScriptTrue("result.a === result.b");
31423142
}
31433143

3144+
TEST_F(ValueSerializerTestWithHostObject, RoundTripJSErrorObject) {
3145+
i::DisableHandleChecksForMockingScope mocking_scope;
3146+
3147+
EXPECT_CALL(serializer_delegate_, HasCustomHostObject(isolate()))
3148+
.WillOnce(Invoke([](Isolate* isolate) { return true; }));
3149+
EXPECT_CALL(serializer_delegate_, IsHostObject(isolate(), _))
3150+
.WillRepeatedly(Invoke([this](Isolate* isolate, Local<Object> object) {
3151+
EXPECT_TRUE(object->IsObject());
3152+
Local<Context> context = isolate->GetCurrentContext();
3153+
return object->Has(context, StringFromUtf8("my_host_object"));
3154+
}));
3155+
// Read/Write HostObject methods are not invoked for non-host JSErrors.
3156+
EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _)).Times(0);
3157+
EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate())).Times(0);
3158+
3159+
RoundTripTest(
3160+
"var e = new Error('before serialize');"
3161+
"({ a: e, get b() { return this.a; } })");
3162+
ExpectScriptTrue("!('my_host_object' in result)");
3163+
ExpectScriptTrue("!('my_host_object' in result.a)");
3164+
ExpectScriptTrue("result.a.message === 'before serialize'");
3165+
ExpectScriptTrue("result.a instanceof Error");
3166+
ExpectScriptTrue("result.a === result.b");
3167+
}
3168+
3169+
TEST_F(ValueSerializerTestWithHostObject, RoundTripHostJSErrorObject) {
3170+
i::DisableHandleChecksForMockingScope mocking_scope;
3171+
3172+
EXPECT_CALL(serializer_delegate_, HasCustomHostObject(isolate()))
3173+
.WillOnce(Invoke([](Isolate* isolate) { return true; }));
3174+
EXPECT_CALL(serializer_delegate_, IsHostObject(isolate(), _))
3175+
.WillRepeatedly(Invoke([this](Isolate* isolate, Local<Object> object) {
3176+
EXPECT_TRUE(object->IsObject());
3177+
Local<Context> context = isolate->GetCurrentContext();
3178+
return object->Has(context, StringFromUtf8("my_host_object"));
3179+
}));
3180+
EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _))
3181+
.WillOnce(Invoke([this](Isolate*, Local<Object> object) {
3182+
EXPECT_TRUE(object->IsObject());
3183+
WriteExampleHostObjectTag();
3184+
return Just(true);
3185+
}));
3186+
EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
3187+
.WillOnce(Invoke([this](Isolate* isolate) {
3188+
EXPECT_TRUE(ReadExampleHostObjectTag());
3189+
Local<Context> context = isolate->GetCurrentContext();
3190+
Local<Object> obj =
3191+
v8::Exception::Error(StringFromUtf8("deserialized")).As<Object>();
3192+
obj->Set(context, StringFromUtf8("my_host_object"), v8::True(isolate))
3193+
.Check();
3194+
return obj;
3195+
}));
3196+
RoundTripTest(
3197+
"var e = new Error('before serialize');"
3198+
"e.my_host_object = true;"
3199+
"({ a: e, get b() { return this.a; } })");
3200+
ExpectScriptTrue("!('my_host_object' in result)");
3201+
ExpectScriptTrue("result.a.my_host_object");
3202+
ExpectScriptTrue("result.a.message === 'deserialized'");
3203+
ExpectScriptTrue("result.a instanceof Error");
3204+
ExpectScriptTrue("result.a === result.b");
3205+
}
3206+
31443207
class ValueSerializerTestWithHostArrayBufferView
31453208
: public ValueSerializerTestWithHostObject {
31463209
protected:

0 commit comments

Comments
 (0)