Skip to content

Commit 6362326

Browse files
osa1Commit Queue
authored and
Commit Queue
committed
[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 is 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, it 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 positional 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.dynamicForwarders` - New field `Translator.dynamicForwarderFunctionType` added for the Wasm function type of forwarder and type checker functions. - Two new code gen utilities added: - `Translator.indexList`: generates code that indexes a Dart list - `Translator.getListLength`: generates code that gets length of a Dart list - New `Reference` extensions added to get type checker function references of members - New runtime library `named_parameters` implements two helper functions for dealing with named argument lists - The library `dynamic_dispatch` is replaced by `dynamic_forwarders`, which consists of two classes: - `DynamicForwarders`: 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 - `_generateFieldSetterTypeCheckerMethod` generates code for a type checker of a setter function. - `_generateProcedureTypeCheckerMethod` generates code for a type checker of a method. Fixes #50367 Change-Id: I2b9d84237c8517bd217166d8acb67e025f0498fb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/272261 Reviewed-by: Joshua Litt <[email protected]> Commit-Queue: Ömer Ağacan <[email protected]> Reviewed-by: Aske Simon Christensen <[email protected]>
1 parent 09a9a89 commit 6362326

12 files changed

+1081
-580
lines changed

pkg/dart2wasm/lib/class_info.dart

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class FieldIndex {
2121
static const boxValue = 1;
2222
static const identityHash = 1;
2323
static const stringArray = 2;
24+
static const listLength = 3;
2425
static const listArray = 4;
2526
static const hashBaseIndex = 2;
2627
static const hashBaseData = 4;
@@ -55,6 +56,7 @@ class FieldIndex {
5556
check(translator.boxedDoubleClass, "value", FieldIndex.boxValue);
5657
check(translator.oneByteStringClass, "_array", FieldIndex.stringArray);
5758
check(translator.twoByteStringClass, "_array", FieldIndex.stringArray);
59+
check(translator.listBaseClass, "_length", FieldIndex.listLength);
5860
check(translator.listBaseClass, "_data", FieldIndex.listArray);
5961
check(translator.hashFieldBaseClass, "_index", FieldIndex.hashBaseIndex);
6062
check(translator.hashFieldBaseClass, "_data", FieldIndex.hashBaseData);

0 commit comments

Comments
 (0)