mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 14:43:32 +00:00
[vm/sendport] Ensure that partially instantiated static closures keep types when sent over SendPort.
Fixes https://github.com/dart-lang/sdk/issues/43343. Change-Id: If2a741ba9b13f7817ff765d83f3f5a920860cb9e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/163133 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
b5f688e938
commit
26e503612a
36
runtime/tests/vm/dart/send_instantiated_fun_test.dart
Normal file
36
runtime/tests/vm/dart/send_instantiated_fun_test.dart
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Verify that partially instantiated generic function remains instantiated
|
||||
// after received via ReceivePort.
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
// Prevent obfuscation.
|
||||
@pragma('vm:entry-point')
|
||||
class Dog {}
|
||||
|
||||
// Prevent obfuscation.
|
||||
@pragma('vm:entry-point')
|
||||
List<T> decodeFrom<T>(String s) {
|
||||
return List();
|
||||
}
|
||||
|
||||
// Prevent obfuscation.
|
||||
@pragma('vm:entry-point')
|
||||
List<Dog> Function(String s) decodeFromDog = decodeFrom;
|
||||
|
||||
void main() async {
|
||||
final receivePort = ReceivePort();
|
||||
receivePort.listen(expectAsync1((data) {
|
||||
print("Received $data");
|
||||
Expect.equals('$data',
|
||||
"[Closure: (String) => List<Dog> from Function 'decodeFrom': static.]");
|
||||
receivePort.close();
|
||||
}));
|
||||
print("Sending $decodeFromDog");
|
||||
receivePort.sendPort.send(<dynamic>[decodeFromDog]);
|
||||
}
|
36
runtime/tests/vm/dart_2/send_instantiated_fun_test.dart
Normal file
36
runtime/tests/vm/dart_2/send_instantiated_fun_test.dart
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Verify that partially instantiated generic function remains instantiated
|
||||
// after received via ReceivePort.
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:async_helper/async_minitest.dart';
|
||||
|
||||
// Prevent obfuscation.
|
||||
@pragma('vm:entry-point')
|
||||
class Dog {}
|
||||
|
||||
// Prevent obfuscation.
|
||||
@pragma('vm:entry-point')
|
||||
List<T> decodeFrom<T>(String s) {
|
||||
return List();
|
||||
}
|
||||
|
||||
// Prevent obfuscation.
|
||||
@pragma('vm:entry-point')
|
||||
List<Dog> Function(String s) decodeFromDog = decodeFrom;
|
||||
|
||||
void main() async {
|
||||
final receivePort = ReceivePort();
|
||||
receivePort.listen(expectAsync1((data) {
|
||||
print("Received $data");
|
||||
Expect.equals('$data',
|
||||
"[Closure: (String) => List<Dog> from Function 'decodeFrom': static.]");
|
||||
receivePort.close();
|
||||
}));
|
||||
print("Sending $decodeFromDog");
|
||||
receivePort.sendPort.send(<dynamic>[decodeFromDog]);
|
||||
}
|
|
@ -399,8 +399,8 @@ void ClosureLayout::WriteTo(SnapshotWriter* writer,
|
|||
// Check if closure is serializable, throw an exception otherwise.
|
||||
FunctionPtr func = writer->IsSerializableClosure(ClosurePtr(this));
|
||||
if (func != Function::null()) {
|
||||
writer->WriteStaticImplicitClosure(object_id, func,
|
||||
writer->GetObjectTags(this));
|
||||
writer->WriteStaticImplicitClosure(
|
||||
object_id, func, writer->GetObjectTags(this), delayed_type_arguments_);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -458,11 +458,25 @@ ObjectPtr SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id,
|
|||
if (func.IsNull()) {
|
||||
SetReadException("Invalid function object found in message.");
|
||||
}
|
||||
TypeArguments& delayed_type_arguments = TypeArguments::Handle(zone());
|
||||
delayed_type_arguments ^= ReadObjectImpl(kAsInlinedObject);
|
||||
|
||||
func = func.ImplicitClosureFunction();
|
||||
ASSERT(!func.IsNull());
|
||||
|
||||
// Return the associated implicit static closure.
|
||||
obj = func.ImplicitStaticClosure();
|
||||
// If delayedtype arguments were provided, create and return new closure with
|
||||
// those, otherwise return associated implicit static closure.
|
||||
// Note that static closures can't have instantiator or function types since
|
||||
// statics can't refer to class type arguments, don't have outer functions.
|
||||
if (!delayed_type_arguments.IsNull()) {
|
||||
const Context& context = Context::Handle(zone());
|
||||
obj = Closure::New(
|
||||
/*instantiator_type_arguments=*/Object::null_type_arguments(),
|
||||
/*function_type_arguments=*/Object::null_type_arguments(),
|
||||
delayed_type_arguments, func, context, Heap::kOld);
|
||||
} else {
|
||||
obj = func.ImplicitStaticClosure();
|
||||
}
|
||||
return obj.raw();
|
||||
}
|
||||
|
||||
|
@ -1313,9 +1327,11 @@ void SnapshotWriter::WriteClassId(ClassLayout* cls) {
|
|||
WriteObjectImpl(cls->name_, kAsInlinedObject);
|
||||
}
|
||||
|
||||
void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id,
|
||||
FunctionPtr func,
|
||||
intptr_t tags) {
|
||||
void SnapshotWriter::WriteStaticImplicitClosure(
|
||||
intptr_t object_id,
|
||||
FunctionPtr func,
|
||||
intptr_t tags,
|
||||
TypeArgumentsPtr delayed_type_arguments) {
|
||||
// Write out the serialization header value for this object.
|
||||
WriteInlinedObjectHeader(object_id);
|
||||
|
||||
|
@ -1333,6 +1349,7 @@ void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id,
|
|||
WriteObjectImpl(library->ptr()->url_, kAsInlinedObject);
|
||||
WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
|
||||
WriteObjectImpl(func->ptr()->name_, kAsInlinedObject);
|
||||
WriteObjectImpl(delayed_type_arguments, kAsInlinedObject);
|
||||
}
|
||||
|
||||
void SnapshotWriter::ArrayWriteTo(intptr_t object_id,
|
||||
|
|
|
@ -623,7 +623,8 @@ class SnapshotWriter : public BaseWriter {
|
|||
|
||||
void WriteStaticImplicitClosure(intptr_t object_id,
|
||||
FunctionPtr func,
|
||||
intptr_t tags);
|
||||
intptr_t tags,
|
||||
TypeArgumentsPtr delayed_type_arguments);
|
||||
|
||||
protected:
|
||||
bool CheckAndWritePredefinedObject(ObjectPtr raw);
|
||||
|
@ -668,7 +669,6 @@ class SnapshotWriter : public BaseWriter {
|
|||
|
||||
friend class ArrayLayout;
|
||||
friend class ClassLayout;
|
||||
friend class ClosureDataLayout;
|
||||
friend class CodeLayout;
|
||||
friend class ContextScopeLayout;
|
||||
friend class DynamicLibraryLayout;
|
||||
|
|
Loading…
Reference in a new issue