Skip to content

Commit 17d7296

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/nnbd/bytecode] Fix reuse of type arguments in bytecode
Type arguments should not be reused if type parameter has a nullability other than non-nullable or undertermined, as instantiating such type parameter may alter the type. Also, this change adds printing of nullability when dumping bytecode and updates expectations accordingly. Fixes language/nnbd/is_type_test/null_is_type_in_legacy_lib_test in bytecode mode. Change-Id: I4378a4e42fa0bf014840b9b1ef09a633c1825e20 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155560 Reviewed-by: Régis Crelier <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 58b6f40 commit 17d7296

15 files changed

+811
-797
lines changed

pkg/vm/lib/bytecode/gen_bytecode.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,9 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
14881488
for (int i = 0; i < typeArgs.length; ++i) {
14891489
final typeArg = typeArgs[i];
14901490
if (!(typeArg is TypeParameterType &&
1491-
typeArg.parameter == functionTypeParameters[i])) {
1491+
typeArg.parameter == functionTypeParameters[i] &&
1492+
(typeArg.nullability == Nullability.nonNullable ||
1493+
typeArg.nullability == Nullability.undetermined))) {
14921494
return false;
14931495
}
14941496
}

pkg/vm/lib/bytecode/object_table.dart

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,20 @@ const String topLevelClassName = '';
335335
String objectKindToString(ObjectKind kind) =>
336336
kind.toString().substring('ObjectKind.k'.length);
337337

338+
String nullabilityToString(Nullability nullability) {
339+
switch (nullability) {
340+
case Nullability.legacy:
341+
return '*';
342+
case Nullability.nullable:
343+
return '?';
344+
case Nullability.undetermined:
345+
return '%';
346+
case Nullability.nonNullable:
347+
return '';
348+
}
349+
throw "Unknown Nullability: $nullability";
350+
}
351+
338352
/// Represents object (library, class, member, closure, type or name) in the
339353
/// object table.
340354
abstract class ObjectHandle extends BytecodeObject {
@@ -763,8 +777,7 @@ class _NeverTypeHandle extends _TypeHandle {
763777
other is _NeverTypeHandle && this.nullability == other.nullability;
764778

765779
@override
766-
// TODO(regis): Print nullability.
767-
String toString() => 'Never';
780+
String toString() => 'Never${nullabilityToString(nullability)}';
768781
}
769782

770783
class _SimpleTypeHandle extends _TypeHandle {
@@ -803,8 +816,7 @@ class _SimpleTypeHandle extends _TypeHandle {
803816
this.nullability == other.nullability;
804817

805818
@override
806-
// TODO(regis): Print nullability.
807-
String toString() => '$class_';
819+
String toString() => '$class_${nullabilityToString(nullability)}';
808820
}
809821

810822
class _TypeParameterHandle extends _TypeHandle {
@@ -857,8 +869,8 @@ class _TypeParameterHandle extends _TypeHandle {
857869
this.nullability == other.nullability;
858870

859871
@override
860-
// TODO(regis): Print nullability.
861-
String toString() => '$parent::TypeParam/$indexInParent';
872+
String toString() =>
873+
'$parent::TypeParam/$indexInParent${nullabilityToString(nullability)}';
862874
}
863875

864876
class _GenericTypeHandle extends _TypeHandle {
@@ -903,8 +915,7 @@ class _GenericTypeHandle extends _TypeHandle {
903915
this.nullability == other.nullability;
904916

905917
@override
906-
// TODO(regis): Print nullability.
907-
String toString() => '$class_ $typeArgs';
918+
String toString() => '$class_ $typeArgs${nullabilityToString(nullability)}';
908919
}
909920

910921
class _RecursiveGenericTypeHandle extends _TypeHandle {
@@ -956,8 +967,8 @@ class _RecursiveGenericTypeHandle extends _TypeHandle {
956967
this.nullability == other.nullability;
957968

958969
@override
959-
// TODO(regis): Print nullability.
960-
String toString() => '(recursive #$id) $class_ $typeArgs';
970+
String toString() =>
971+
'(recursive #$id) $class_ $typeArgs${nullabilityToString(nullability)}';
961972
}
962973

963974
class _RecursiveTypeRefHandle extends _TypeHandle {
@@ -1009,7 +1020,6 @@ class NameAndType {
10091020
this.type == other.type;
10101021

10111022
@override
1012-
// TODO(regis): Print nullability.
10131023
String toString() => '$type ${name.name}';
10141024
}
10151025

@@ -1152,7 +1162,6 @@ class _FunctionTypeHandle extends _TypeHandle {
11521162
this.returnType == other.returnType;
11531163

11541164
@override
1155-
// TODO(regis): Print nullability.
11561165
String toString() {
11571166
StringBuffer sb = new StringBuffer();
11581167
sb.write('FunctionType');
@@ -1173,7 +1182,7 @@ class _FunctionTypeHandle extends _TypeHandle {
11731182
}
11741183
sb.write('{ ${namedParams.join(', ')} }');
11751184
}
1176-
sb.write(') -> ');
1185+
sb.write(')${nullabilityToString(nullability)} -> ');
11771186
sb.write(returnType);
11781187
return sb.toString();
11791188
}

pkg/vm/testcases/bytecode/asserts.dart.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Class '', script = '#lib'
1111

1212

1313
Function 'test1', static, reflectable, debuggable
14-
parameters [dart:core::bool 'condition'] (required: 1)
14+
parameters [dart:core::bool* 'condition'] (required: 1)
1515
return-type void
1616

1717
Bytecode {
@@ -37,7 +37,7 @@ ConstantPool {
3737

3838

3939
Function 'test2', static, reflectable, debuggable
40-
parameters [FunctionType () -> dart:core::bool 'condition', FunctionType () -> dart:core::String 'message'] (required: 2)
40+
parameters [FunctionType ()* -> dart:core::bool* 'condition', FunctionType ()* -> dart:core::String* 'message'] (required: 2)
4141
return-type void
4242

4343
Bytecode {

pkg/vm/testcases/bytecode/async.dart.expect

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Library '#lib'
99

1010
Class '', script = '#lib'
1111

12-
Field 'asyncInFieldInitializer', type = FunctionType (dart:async::Future < dart:core::int >) -> dart:async::Future < dart:core::Null >, getter = 'get:asyncInFieldInitializer', reflectable, static, has-initializer
12+
Field 'asyncInFieldInitializer', type = FunctionType (dart:async::Future < dart:core::int* >*)* -> dart:async::Future < dart:core::Null? >*, getter = 'get:asyncInFieldInitializer', reflectable, static, has-initializer
1313
initializer
1414
Bytecode {
1515
Entry 3
@@ -34,11 +34,11 @@ ConstantPool {
3434
[0] = ClosureFunction 0
3535
[1] = InstanceField dart:core::_Closure::_context (field)
3636
[2] = Reserved
37-
[3] = Type dart:async::Future < dart:core::int >
37+
[3] = Type dart:async::Future < dart:core::int* >*
3838
[4] = ObjectRef 'x'
3939
[5] = SubtypeTestCache
4040
[6] = Class dart:async::_AsyncAwaitCompleter
41-
[7] = ObjectRef < dart:core::Null >
41+
[7] = ObjectRef < dart:core::Null? >
4242
[8] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
4343
[9] = Reserved
4444
[10] = ClosureFunction 1
@@ -67,7 +67,7 @@ ConstantPool {
6767
[33] = Reserved
6868
[34] = EndClosureFunctionScope
6969
}
70-
Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' async (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
70+
Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' async (dart:async::Future < dart:core::int* >* x) -> dart:async::Future < dart:core::Null? >*
7171
ClosureCode {
7272
EntryFixed 2, 4
7373
Push FP[-6]
@@ -233,7 +233,7 @@ L1:
233233

234234
Function 'foo', static, reflectable, async
235235
parameters [] (required: 0)
236-
return-type dart:async::Future < dart:core::int >
236+
return-type dart:async::Future < dart:core::int* >*
237237

238238
Bytecode {
239239
Entry 7
@@ -293,7 +293,7 @@ Bytecode {
293293
}
294294
ConstantPool {
295295
[0] = Class dart:async::_AsyncAwaitCompleter
296-
[1] = ObjectRef < dart:core::int >
296+
[1] = ObjectRef < dart:core::int* >
297297
[2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
298298
[3] = Reserved
299299
[4] = ClosureFunction 0
@@ -380,8 +380,8 @@ L1:
380380

381381

382382
Function 'simpleAsyncAwait', static, reflectable, async
383-
parameters [dart:async::Future < dart:core::int > 'a', dart:async::Future < dart:core::int > 'b'] (required: 2)
384-
return-type dart:async::Future < dart:core::int >
383+
parameters [dart:async::Future < dart:core::int* >* 'a', dart:async::Future < dart:core::int* >* 'b'] (required: 2)
384+
return-type dart:async::Future < dart:core::int* >*
385385

386386
Bytecode {
387387
Entry 4
@@ -449,7 +449,7 @@ Bytecode {
449449
}
450450
ConstantPool {
451451
[0] = Class dart:async::_AsyncAwaitCompleter
452-
[1] = ObjectRef < dart:core::int >
452+
[1] = ObjectRef < dart:core::int* >
453453
[2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
454454
[3] = Reserved
455455
[4] = ClosureFunction 0
@@ -605,8 +605,8 @@ L1:
605605

606606

607607
Function 'loops', static, reflectable, async
608-
parameters [dart:core::List < dart:core::int > 'list'] (required: 1)
609-
return-type dart:async::Future < dart:core::int >
608+
parameters [dart:core::List < dart:core::int* >* 'list'] (required: 1)
609+
return-type dart:async::Future < dart:core::int* >*
610610

611611
Bytecode {
612612
Entry 4
@@ -671,7 +671,7 @@ Bytecode {
671671
}
672672
ConstantPool {
673673
[0] = Class dart:async::_AsyncAwaitCompleter
674-
[1] = ObjectRef < dart:core::int >
674+
[1] = ObjectRef < dart:core::int* >
675675
[2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
676676
[3] = Reserved
677677
[4] = ClosureFunction 0
@@ -951,8 +951,8 @@ L1:
951951

952952

953953
Function 'tryCatchRethrow', static, reflectable, async
954-
parameters [dart:async::Future < dart:core::int > 'a', dart:async::Future < dart:core::int > 'b', dart:async::Future < dart:core::int > 'c'] (required: 3)
955-
return-type dart:async::Future < dart:core::int >
954+
parameters [dart:async::Future < dart:core::int* >* 'a', dart:async::Future < dart:core::int* >* 'b', dart:async::Future < dart:core::int* >* 'c'] (required: 3)
955+
return-type dart:async::Future < dart:core::int* >*
956956

957957
Bytecode {
958958
Entry 4
@@ -1023,7 +1023,7 @@ Bytecode {
10231023
}
10241024
ConstantPool {
10251025
[0] = Class dart:async::_AsyncAwaitCompleter
1026-
[1] = ObjectRef < dart:core::int >
1026+
[1] = ObjectRef < dart:core::int* >
10271027
[2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
10281028
[3] = Reserved
10291029
[4] = ClosureFunction 0
@@ -1033,7 +1033,7 @@ ConstantPool {
10331033
[8] = DirectCall 'dart:async::_awaitHelper', ArgDesc num-args 4, num-type-args 0, names []
10341034
[9] = Reserved
10351035
[10] = Type dynamic
1036-
[11] = Type dart:core::Error
1036+
[11] = Type dart:core::Error*
10371037
[12] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names []
10381038
[13] = Reserved
10391039
[14] = ObjectRef 'fin'
@@ -1480,7 +1480,7 @@ L1:
14801480

14811481

14821482
Function 'closure', static, reflectable, debuggable
1483-
parameters [dart:async::Future < dart:core::int > 'a'] (required: 1)
1483+
parameters [dart:async::Future < dart:core::int* >* 'a'] (required: 1)
14841484
return-type dynamic
14851485

14861486
Bytecode {
@@ -1517,7 +1517,7 @@ ConstantPool {
15171517
[1] = InstanceField dart:core::_Closure::_context (field)
15181518
[2] = Reserved
15191519
[3] = Class dart:async::_AsyncAwaitCompleter
1520-
[4] = ObjectRef < dart:core::int >
1520+
[4] = ObjectRef < dart:core::int* >
15211521
[5] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
15221522
[6] = Reserved
15231523
[7] = ClosureFunction 1
@@ -1549,7 +1549,7 @@ ConstantPool {
15491549
[33] = Reserved
15501550
[34] = EndClosureFunctionScope
15511551
}
1552-
Closure #lib::closure::'nested' async () -> dart:async::Future < dart:core::int >
1552+
Closure #lib::closure::'nested' async () -> dart:async::Future < dart:core::int* >*
15531553
ClosureCode {
15541554
EntryFixed 1, 4
15551555
Push FP[-5]
@@ -1776,8 +1776,8 @@ L1:
17761776

17771777

17781778
Function 'testAssert', static, reflectable, async
1779-
parameters [dart:async::Future < dart:core::int > 'a'] (required: 1)
1780-
return-type dart:async::Future < dart:core::int >
1779+
parameters [dart:async::Future < dart:core::int* >* 'a'] (required: 1)
1780+
return-type dart:async::Future < dart:core::int* >*
17811781

17821782
Bytecode {
17831783
Entry 4
@@ -1842,7 +1842,7 @@ Bytecode {
18421842
}
18431843
ConstantPool {
18441844
[0] = Class dart:async::_AsyncAwaitCompleter
1845-
[1] = ObjectRef < dart:core::int >
1845+
[1] = ObjectRef < dart:core::int* >
18461846
[2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
18471847
[3] = Reserved
18481848
[4] = ClosureFunction 0

0 commit comments

Comments
 (0)