@@ -509,17 +509,23 @@ initialization it complete.
509509In the _ shared ** everything** multithreading_ shared fields can be allowed to
510510contain anything - including instances of mutable Dart classes. However,
511511initially I propose to limit shared fields by allowing only _ trivially shareable
512- types_ . These types are those which already can pass through
513- ` SendPort ` without copying:
514-
515- - strings;
516- - numbers;
517- - [ deeply immutable] [ ] types;
518- - builtin implementations of ` SendPort ` and ` TypedData ` ;
519- - tear-offs of static methods;
520- - closures which capture variables of trivially shareable types;
512+ types_ , which include:
521513
522- Sharing of these types don't break isolate boundaries.
514+ - Objects which do not contain mutable state and thus can already pass through
515+ ` SendPort ` without copying:
516+ - strings;
517+ - numbers;
518+ - instances of [ deeply immutable] [ ] types;
519+ - instances of internal implementation of ` SendPort ` ;
520+ - tear-offs of static methods;
521+ - compile time constants;
522+ - Objects which contain non-structural (binary) mutable state:
523+ - ` TypedData `
524+ - ` Struct ` instances
525+ - Closures which capture variables which are annotated with ` @pragma('vm:shared') `
526+ and are of trivially shareable types;
527+
528+ Sharing of these types does not break isolate boundaries.
523529
524530[ deeply immutable ] : https://github.com/dart-lang/sdk/blob/bb59b5c72c52369e1b0d21940008c4be7e6d43b3/runtime/docs/deeply_immutable.md
525531
@@ -553,6 +559,12 @@ Sharing of these types don't break isolate boundaries.
553559> Furthermore, shared fields of ` int ` and ` double ` types are allowed to exhibit
554560> _ tearing_ on 32-bit platforms.
555561
562+ > [ !NOTE]
563+ >
564+ > There is no static type marker for a trivially shareable closure. For convenience
565+ > reasons we should allow writing ` @pragma('vm:shared') void Function() foo; ` but
566+ > will have to check shareability in runtime when such variable is initialized.
567+
556568## Shared Isolates
557569
558570Lets take another look at the following example:
@@ -678,16 +690,29 @@ associated with that:
678690
679691In _ shared ** everything** multithreading_ world ` callback ` can be allowed to
680692capture arbitrary state, however in _ shared ** native memory** multithreading_
681- this state has to be restricted to trivially shareable types:
693+ this state has to be restricted to trivially shareable types. To make it
694+ completely unambigious we impose an additional requirement that all variables
695+ captured by a closure will need to be annotated with ` @pragma('vm:shared') ` :
696+
682697
683698``` dart
684- // This code is okay because `int` is trivially shareable.
699+ // This code is okay because the variable is annotated and `int` is
700+ // trivially shareable.
701+ @pragma('vm:shared')
702+ int counter = 0;
703+ NativeCallable.shared(() {
704+ counter++;
705+ });
706+
707+ // This code causes a runtime error because `counter` is not not
708+ // annotated with vm:shared pragma.
685709int counter = 0;
686710NativeCallable.shared(() {
687711 counter++;
688712});
689713
690714// This code is not okay because `List<T>` is not trivially shareable.
715+ @pragma('vm:shared')
691716List<int> list = [];
692717NativeCallable.shared(() {
693718 list.add(1);
0 commit comments