Skip to content

Commit fa43799

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/bytecode] Check number of type arguments in non-generic closures
Fixes #39283 Change-Id: I5a5fdf158c6a7ce068be36754ea0487cb754584b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124470 Reviewed-by: Régis Crelier <regis@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
1 parent a01c3b4 commit fa43799

File tree

6 files changed

+47
-1
lines changed

6 files changed

+47
-1
lines changed

pkg/vm/lib/bytecode/gen_bytecode.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,14 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
19431943
_handleDefaultTypeArguments(function, done);
19441944

19451945
asm.bind(done);
1946+
} else if (isClosure &&
1947+
!(parentFunction != null &&
1948+
parentFunction.dartAsyncMarker != AsyncMarker.Sync)) {
1949+
// Closures can be called dynamically with arbitrary arguments,
1950+
// so they should check number of type arguments, even if
1951+
// closure is not generic.
1952+
// Synthetic async_op closures don't need this check.
1953+
asm.emitCheckFunctionTypeArgs(0, locals.scratchVarIndexInFrame);
19461954
}
19471955

19481956
// Open initial scope before the first CheckStack, as VM might

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ ClosureCode {
7373
Push FP[-6]
7474
LoadFieldTOS CP#1
7575
PopLocal r0
76+
CheckFunctionTypeArgs 0, r1
7677
CheckStack 0
7778
AllocateContext 0, 9
7879
PopLocal r0
@@ -1560,6 +1561,7 @@ ClosureCode {
15601561
Push FP[-5]
15611562
LoadFieldTOS CP#1
15621563
PopLocal r0
1564+
CheckFunctionTypeArgs 0, r1
15631565
CheckStack 0
15641566
AllocateContext 1, 9
15651567
StoreLocal r1

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ ClosureCode {
6969
Push FP[-6]
7070
LoadFieldTOS CP#1
7171
PopLocal r0
72+
CheckFunctionTypeArgs 0, r1
7273
CheckStack 0
7374
JumpIfUnchecked L1
7475
Push FP[-5]
@@ -768,6 +769,7 @@ ClosureCode {
768769
Push FP[-5]
769770
LoadFieldTOS CP#1
770771
PopLocal r1
772+
CheckFunctionTypeArgs 0, r2
771773
CheckStack 0
772774
Push FP[-5]
773775
LoadFieldTOS CP#6
@@ -987,6 +989,7 @@ ClosureCode {
987989
Push FP[-6]
988990
LoadFieldTOS CP#1
989991
PopLocal r0
992+
CheckFunctionTypeArgs 0, r1
990993
CheckStack 0
991994
AllocateContext 1, 2
992995
StoreLocal r1
@@ -1057,6 +1060,7 @@ ClosureCode {
10571060
Push FP[-5]
10581061
LoadFieldTOS CP#1
10591062
PopLocal r0
1063+
CheckFunctionTypeArgs 0, r1
10601064
CheckStack 0
10611065
Push r0
10621066
LoadContextParent
@@ -1085,6 +1089,7 @@ ClosureCode {
10851089
Push FP[-5]
10861090
LoadFieldTOS CP#1
10871091
PopLocal r0
1092+
CheckFunctionTypeArgs 0, r1
10881093
CheckStack 0
10891094
Push r0
10901095
LoadContextVar 0, 0
@@ -1242,6 +1247,7 @@ ClosureCode {
12421247
Push FP[-5]
12431248
LoadFieldTOS CP#5
12441249
PopLocal r0
1250+
CheckFunctionTypeArgs 0, r1
12451251
CheckStack 0
12461252
Push r0
12471253
LoadContextVar 1, 0
@@ -1258,6 +1264,7 @@ ClosureCode {
12581264
Push FP[-6]
12591265
LoadFieldTOS CP#5
12601266
PopLocal r0
1267+
CheckFunctionTypeArgs 0, r1
12611268
CheckStack 0
12621269
JumpIfUnchecked L1
12631270
Push FP[-5]
@@ -1360,6 +1367,7 @@ ClosureCode {
13601367
Push FP[-5]
13611368
LoadFieldTOS CP#7
13621369
PopLocal r0
1370+
CheckFunctionTypeArgs 0, r1
13631371
CheckStack 0
13641372
Push r0
13651373
Push r0
@@ -1457,6 +1465,7 @@ ClosureCode {
14571465
Push FP[-5]
14581466
LoadFieldTOS CP#5
14591467
PopLocal r0
1468+
CheckFunctionTypeArgs 0, r1
14601469
CheckStack 0
14611470
Push r0
14621471
LoadContextVar 0, 0
@@ -1515,6 +1524,7 @@ ClosureCode {
15151524
Push FP[-5]
15161525
LoadFieldTOS CP#1
15171526
PopLocal r0
1527+
CheckFunctionTypeArgs 0, r1
15181528
CheckStack 0
15191529
AllocateClosure CP#3
15201530
StoreLocal r3
@@ -1548,6 +1558,7 @@ ClosureCode {
15481558
Push FP[-5]
15491559
LoadFieldTOS CP#1
15501560
PopLocal r0
1561+
CheckFunctionTypeArgs 0, r1
15511562
CheckStack 0
15521563
PushNull
15531564
ReturnTOS

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ ClosureCode {
341341
Push FP[-5]
342342
LoadFieldTOS CP#1
343343
PopLocal r0
344+
CheckFunctionTypeArgs 0, r1
344345
CheckStack 0
345346
Push r0
346347
PopLocal r2
@@ -377,6 +378,7 @@ ClosureCode {
377378
Push FP[-5]
378379
LoadFieldTOS CP#1
379380
PopLocal r0
381+
CheckFunctionTypeArgs 0, r1
380382
CheckStack 0
381383
Push r0
382384
PopLocal r2
@@ -723,6 +725,7 @@ ClosureCode {
723725
Push FP[-5]
724726
LoadFieldTOS CP#7
725727
PopLocal r0
728+
CheckFunctionTypeArgs 0, r1
726729
CheckStack 0
727730
Push r0
728731
LoadContextVar 0, 0
@@ -831,6 +834,7 @@ ClosureCode {
831834
Push FP[-5]
832835
LoadFieldTOS CP#1
833836
PopLocal r0
837+
CheckFunctionTypeArgs 0, r1
834838
CheckStack 0
835839
Push r0
836840
LoadContextVar 0, 0

runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,6 @@ void BytecodeFlowGraphBuilder::BuildCheckFunctionTypeArgs() {
696696

697697
const intptr_t expected_num_type_args = DecodeOperandA().value();
698698
LocalVariable* type_args_var = LocalVariableAt(DecodeOperandE().value());
699-
ASSERT(function().IsGeneric());
700699

701700
if (throw_no_such_method_ == nullptr) {
702701
throw_no_such_method_ = B->BuildThrowNoSuchMethod();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "package:expect/expect.dart";
6+
7+
class A {
8+
dynamic foo(a) {
9+
baz() {
10+
Expect.fail('Should not be reachable');
11+
}
12+
13+
return baz;
14+
}
15+
}
16+
17+
main() {
18+
Expect.throws(() {
19+
dynamic x = A().foo(1);
20+
x<List>();
21+
}, (e) => e is NoSuchMethodError);
22+
}

0 commit comments

Comments
 (0)