google / protobuf.dart

Runtime library for Dart protobufs
https://pub.dev/packages/protobuf
BSD 3-Clause "New" or "Revised" License
525 stars 183 forks source link

Document strange downcast conventions used in the library, add a function for downcasts #712

Open osa1 opened 2 years ago

osa1 commented 2 years ago

In protobuf library, for downcasting we use implicit cast syntax:

<type> <var> = <expr>

instead of explicit cast syntax:

[var|final] <var> = <expr> as <type>

The reason is because dart2js compiles these two differently, and the implicit cast syntax is much more efficient.

(AOT and JIT treat both the same way)

For a reader it won't be obvious why we do this. We should create a function for downcasting that uses implicit cast syntax, and document why we use it. @mkustermann suggests

/// Cast value down using implicit `as` check.
/// 
/// This will impact dart2js which does not perform implicit `as` in -O4 (but does perform explicit `as` checks)
@pragma('vm:prefer-inline')
@pragma('dart2js:Inline')
T downcastAs<T>(dynamic value) => value;
mkustermann commented 2 years ago

It may need to be @pragma('dart2js:tryInline'). It could also be written with explicit as check and using @pragma('dart2js:as:trust').

rakudrama commented 2 years ago

Another consideration is the debug performance in DDC which never inlines methods. It might be better to put @pragma('dart2js:as:trust') on the method that contains the cast rather than add an 'abstraction'.

I recently added some documentation of the dart2js pragmas: https://dart.googlesource.com/sdk/+/f503281917b74ac0571bd4bc5c37789006cdef8e/pkg/compiler/doc/pragmas.md