You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[dart2wasm] Implement missing features in dynamic invocations:
This reimplements dynamic call code generation to add support for type
checking, named parameters (optional and required), and fixes a few
related bugs on the way.
Currently we do not try to be as efficient as possible. The goal with
this patch to implement it correctly.
Summary of the changes:
- For every dynamic access kind and member name, we generate a new
"forwarder" function. Dynamic gets, sets, and invocations are compiled
to calls to the forwarders with the right access kind (invocation,
get, set) and member name.
For example, if the program has dynamic invocation of a member "f", we
create an "invocation forwarder for f". If it has a dynamic get of a
member "x", we generate "getter forwarder for x".
- Forwarder functions take 4 arguments:
- Receiver of the invocation, get, or set.
- A Dart list for type arguments in the invocation. For gets and sets
the list is empty.
- A Dart list for positional arguments in the invocation. For gets the
list is empty. For sets, the list only has one element.
- A Dart list for named arguments. For gets and sets the list is
empty. The list has alternating elements of type `Symbol` and
`Object?`, for the name and value of the named parameters.
- A forwarder function compares receiver class ID with the potential
targets of the call. When it finds a match, if compares the callee
"shape" with the parameters passed in the call site.
As it compares the shapes it adjusts argument lists:
- Creates default values for missing optional and named arguments
- Reorders the named argument list to match order expected by the
callee
If it can't find a matching class ID and a member with the right name
and shape, it calls `noSuchMethod` on the receiver.
If it finds a matching class ID and a member, it calls the "type
checker" for the member, passing the original receiver and adjusted
argument lists.
- A "type checker" implements argument type checking for a member, and
it's a member of the same class as the member it's checking types
for. This is to allow accessing class-bound type parameters when
generating type checking code.
- Type checking is implemented using `_isSubtype` on arguments in the
lists.
- When type checking is successful a type checker calls the original
member, passing the arguments as expected by the member.
If type checking is unsuccessful it throws a type error.
Most of the changes are for generating Wasm functions that compare
shapes, adjusts argument lists, and checks types.
Changes to members:
- `Translator.dynamics` fields is renamed to `Translator.forwarders`
- New field `Translator.forwarderFunctionType` added for the Wasm
function type of forwarder and type checker functions.
- Two new code gen utilities added:
- `Translator.indexArray`: generates code that indexes a Dart array
- `Translator.getArrayLength`: generates code that gets length of a
Dart array
- New `Reference` extensions added to get type checker function
reference of members
- New library `named_parameters` implements two helper functions for
dealing with named argument lists
- The library `dynamic_dispatch` is rewritten and now consists of two
classes:
- `Forwarders`: maintains mapping from call kind (get, set,
invocation) and member name to forwarder functions.
- `Forwarder`: a single forwarder, implements code generation for
forwarder functions.
- `CodeGenerator` gets 3 new members:
- `_callForwader` generates call to a forwarder
- `generateSetterTypeCheckerMethod` generates code for a type checker
of a setter function.
- `generateInvocationTypeCheckerMethod` generates code for a type
checker of a method.
(TODO: This should be renamed to `generateMethodTypeCheckerMethod`
for consistency)
Fixesdart-lang#50367
Change-Id: I2b9d84237c8517bd217166d8acb67e025f0498fb
0 commit comments