Skip to content

Commit 26e5036

Browse files
aamcommit-bot@chromium.org
authored andcommitted
[vm/sendport] Ensure that partially instantiated static closures keep types when sent over SendPort.
Fixes #43343. Change-Id: If2a741ba9b13f7817ff765d83f3f5a920860cb9e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/163133 Commit-Queue: Alexander Aprelev <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent b5f688e commit 26e5036

File tree

5 files changed

+98
-9
lines changed

5 files changed

+98
-9
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Verify that partially instantiated generic function remains instantiated
6+
// after received via ReceivePort.
7+
8+
import 'dart:isolate';
9+
import 'package:expect/expect.dart';
10+
import 'package:async_helper/async_minitest.dart';
11+
12+
// Prevent obfuscation.
13+
@pragma('vm:entry-point')
14+
class Dog {}
15+
16+
// Prevent obfuscation.
17+
@pragma('vm:entry-point')
18+
List<T> decodeFrom<T>(String s) {
19+
return List();
20+
}
21+
22+
// Prevent obfuscation.
23+
@pragma('vm:entry-point')
24+
List<Dog> Function(String s) decodeFromDog = decodeFrom;
25+
26+
void main() async {
27+
final receivePort = ReceivePort();
28+
receivePort.listen(expectAsync1((data) {
29+
print("Received $data");
30+
Expect.equals('$data',
31+
"[Closure: (String) => List<Dog> from Function 'decodeFrom': static.]");
32+
receivePort.close();
33+
}));
34+
print("Sending $decodeFromDog");
35+
receivePort.sendPort.send(<dynamic>[decodeFromDog]);
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Verify that partially instantiated generic function remains instantiated
6+
// after received via ReceivePort.
7+
8+
import 'dart:isolate';
9+
import 'package:expect/expect.dart';
10+
import 'package:async_helper/async_minitest.dart';
11+
12+
// Prevent obfuscation.
13+
@pragma('vm:entry-point')
14+
class Dog {}
15+
16+
// Prevent obfuscation.
17+
@pragma('vm:entry-point')
18+
List<T> decodeFrom<T>(String s) {
19+
return List();
20+
}
21+
22+
// Prevent obfuscation.
23+
@pragma('vm:entry-point')
24+
List<Dog> Function(String s) decodeFromDog = decodeFrom;
25+
26+
void main() async {
27+
final receivePort = ReceivePort();
28+
receivePort.listen(expectAsync1((data) {
29+
print("Received $data");
30+
Expect.equals('$data',
31+
"[Closure: (String) => List<Dog> from Function 'decodeFrom': static.]");
32+
receivePort.close();
33+
}));
34+
print("Sending $decodeFromDog");
35+
receivePort.sendPort.send(<dynamic>[decodeFromDog]);
36+
}

runtime/vm/raw_object_snapshot.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,8 @@ void ClosureLayout::WriteTo(SnapshotWriter* writer,
399399
// Check if closure is serializable, throw an exception otherwise.
400400
FunctionPtr func = writer->IsSerializableClosure(ClosurePtr(this));
401401
if (func != Function::null()) {
402-
writer->WriteStaticImplicitClosure(object_id, func,
403-
writer->GetObjectTags(this));
402+
writer->WriteStaticImplicitClosure(
403+
object_id, func, writer->GetObjectTags(this), delayed_type_arguments_);
404404
return;
405405
}
406406

runtime/vm/snapshot.cc

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -458,11 +458,25 @@ ObjectPtr SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
458458
if (func.IsNull()) {
459459
SetReadException("Invalid function object found in message.");
460460
}
461+
TypeArguments& delayed_type_arguments = TypeArguments::Handle(zone());
462+
delayed_type_arguments ^= ReadObjectImpl(kAsInlinedObject);
463+
461464
func = func.ImplicitClosureFunction();
462465
ASSERT(!func.IsNull());
463466

464-
// Return the associated implicit static closure.
465-
obj = func.ImplicitStaticClosure();
467+
// If delayedtype arguments were provided, create and return new closure with
468+
// those, otherwise return associated implicit static closure.
469+
// Note that static closures can't have instantiator or function types since
470+
// statics can't refer to class type arguments, don't have outer functions.
471+
if (!delayed_type_arguments.IsNull()) {
472+
const Context& context = Context::Handle(zone());
473+
obj = Closure::New(
474+
/*instantiator_type_arguments=*/Object::null_type_arguments(),
475+
/*function_type_arguments=*/Object::null_type_arguments(),
476+
delayed_type_arguments, func, context, Heap::kOld);
477+
} else {
478+
obj = func.ImplicitStaticClosure();
479+
}
466480
return obj.raw();
467481
}
468482

@@ -1313,9 +1327,11 @@ void SnapshotWriter::WriteClassId(ClassLayout* cls) {
13131327
WriteObjectImpl(cls->name_, kAsInlinedObject);
13141328
}
13151329

1316-
void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id,
1317-
FunctionPtr func,
1318-
intptr_t tags) {
1330+
void SnapshotWriter::WriteStaticImplicitClosure(
1331+
intptr_t object_id,
1332+
FunctionPtr func,
1333+
intptr_t tags,
1334+
TypeArgumentsPtr delayed_type_arguments) {
13191335
// Write out the serialization header value for this object.
13201336
WriteInlinedObjectHeader(object_id);
13211337

@@ -1333,6 +1349,7 @@ void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id,
13331349
WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
13341350
WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
13351351
WriteObjectImpl(func->ptr()->name_, kAsInlinedObject);
1352+
WriteObjectImpl(delayed_type_arguments, kAsInlinedObject);
13361353
}
13371354

13381355
void SnapshotWriter::ArrayWriteTo(intptr_t object_id,

runtime/vm/snapshot.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,8 @@ class SnapshotWriter : public BaseWriter {
623623

624624
void WriteStaticImplicitClosure(intptr_t object_id,
625625
FunctionPtr func,
626-
intptr_t tags);
626+
intptr_t tags,
627+
TypeArgumentsPtr delayed_type_arguments);
627628

628629
protected:
629630
bool CheckAndWritePredefinedObject(ObjectPtr raw);
@@ -668,7 +669,6 @@ class SnapshotWriter : public BaseWriter {
668669

669670
friend class ArrayLayout;
670671
friend class ClassLayout;
671-
friend class ClosureDataLayout;
672672
friend class CodeLayout;
673673
friend class ContextScopeLayout;
674674
friend class DynamicLibraryLayout;

0 commit comments

Comments
 (0)