Skip to content

Commit ac7f580

Browse files
jensjohacommit-bot@chromium.org
authored andcommitted
Support Kernel Instantiation node in VMs constant evaluator
Fixes #32268. Bug: 32268 Change-Id: I7d2ebc28d19aca623460cd1dacc86b64893810ac Reviewed-on: https://dart-review.googlesource.com/42949 Commit-Queue: Jens Johansen <[email protected]> Reviewed-by: Lasse R.H. Nielsen <[email protected]> Reviewed-by: Vyacheslav Egorov <[email protected]>
1 parent cc3e062 commit ac7f580

6 files changed

+175
-1
lines changed

runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2777,6 +2777,9 @@ Instance& StreamingConstantEvaluator::EvaluateExpression(intptr_t offset,
27772777
case kLet:
27782778
EvaluateLet();
27792779
break;
2780+
case kInstantiation:
2781+
EvaluatePartialTearoffInstantiation();
2782+
break;
27802783
case kBigIntLiteral:
27812784
EvaluateBigIntLiteral();
27822785
break;
@@ -3394,6 +3397,41 @@ void StreamingConstantEvaluator::EvaluateLet() {
33943397
EvaluateExpression(builder_->ReaderOffset(), false); // read body
33953398
}
33963399

3400+
void StreamingConstantEvaluator::EvaluatePartialTearoffInstantiation() {
3401+
// This method call wasn't cached, so receiver et al. isn't cached either.
3402+
const Instance& receiver =
3403+
EvaluateExpression(builder_->ReaderOffset(), false); // read receiver.
3404+
if (!receiver.IsClosure()) {
3405+
H.ReportError(script_, TokenPosition::kNoSource, "Expected closure.");
3406+
}
3407+
const Closure& old_closure = Closure::Cast(receiver);
3408+
3409+
// read type arguments.
3410+
intptr_t num_type_args = builder_->ReadListLength();
3411+
const TypeArguments* type_args = &T.BuildTypeArguments(num_type_args);
3412+
// Even if all dynamic types are passed in, we need to put a vector in here to
3413+
// distinguish this partially applied tearoff from a normal tearoff. This is
3414+
// necessary because the tearoff wrapper (BuildGraphOfImplicitClosureFunction)
3415+
// needs to throw NSM if type arguments are passed to a partially applied
3416+
// tearoff.
3417+
if (type_args->IsNull()) {
3418+
type_args =
3419+
&TypeArguments::ZoneHandle(Z, TypeArguments::New(num_type_args));
3420+
for (intptr_t i = 0; i < num_type_args; ++i) {
3421+
type_args->SetTypeAt(i, Type::ZoneHandle(Z, Type::DynamicType()));
3422+
}
3423+
}
3424+
3425+
// Create new closure with the type arguments inserted, and other things
3426+
// copied over.
3427+
Closure& new_closure = Closure::Handle(
3428+
Z, Closure::New(TypeArguments::Handle(
3429+
Z, old_closure.instantiator_type_arguments()),
3430+
*type_args, Function::Handle(Z, old_closure.function()),
3431+
Context::Handle(Z, old_closure.context()), Heap::kOld));
3432+
result_ = H.Canonicalize(new_closure);
3433+
}
3434+
33973435
void StreamingConstantEvaluator::EvaluateBigIntLiteral() {
33983436
const String& value =
33993437
H.DartString(builder_->ReadStringReference()); // read string reference.

runtime/vm/compiler/frontend/kernel_binary_flowgraph.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,7 @@ class StreamingConstantEvaluator {
872872
void EvaluateListLiteralInternal();
873873
void EvaluateMapLiteralInternal();
874874
void EvaluateLet();
875+
void EvaluatePartialTearoffInstantiation();
875876
void EvaluateBigIntLiteral();
876877
void EvaluateStringLiteral();
877878
void EvaluateIntLiteral(uint8_t payload);

tests/language_2/language_2_dart2js.status

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,13 @@ mixin_type_parameter_inference_test/12: CompileTimeError
980980
mixin_type_parameter_inference_test/13: CompileTimeError
981981
mixin_type_parameter_inference_test/16: CompileTimeError
982982
mixin_type_parameter_inference_test/none: CompileTimeError
983+
partial_tearoff_instantiation_test/02: CompileTimeError
984+
partial_tearoff_instantiation_test/04: CompileTimeError
985+
partial_tearoff_instantiation_test/05: Pass # for the wrong reason.
986+
partial_tearoff_instantiation_test/06: Pass # for the wrong reason.
987+
partial_tearoff_instantiation_test/07: Pass # for the wrong reason.
988+
partial_tearoff_instantiation_test/08: Pass # for the wrong reason.
989+
partial_tearoff_instantiation_test/none: CompileTimeError
983990

984991
[ $compiler == dart2js && $dart2js_with_kernel && $fast_startup && $strong ]
985992
assertion_initializer_const_error2_test/none: CompileTimeError
@@ -3566,6 +3573,14 @@ override_inheritance_no_such_method_test/12: MissingCompileTimeError
35663573
override_inheritance_no_such_method_test/13: MissingCompileTimeError
35673574
override_method_with_field_test/02: MissingCompileTimeError
35683575
part2_test/01: MissingCompileTimeError
3576+
partial_tearoff_instantiation_test/01: MissingCompileTimeError
3577+
partial_tearoff_instantiation_test/02: MissingRuntimeError
3578+
partial_tearoff_instantiation_test/03: MissingCompileTimeError
3579+
partial_tearoff_instantiation_test/04: MissingRuntimeError
3580+
partial_tearoff_instantiation_test/05: MissingCompileTimeError
3581+
partial_tearoff_instantiation_test/06: MissingCompileTimeError
3582+
partial_tearoff_instantiation_test/07: MissingCompileTimeError
3583+
partial_tearoff_instantiation_test/08: MissingCompileTimeError
35693584
positional_parameters_type_test/01: MissingCompileTimeError
35703585
positional_parameters_type_test/02: MissingCompileTimeError
35713586
prefix16_test/00: MissingCompileTimeError

tests/language_2/language_2_kernel.status

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ override_inheritance_no_such_method_test/09: MissingCompileTimeError
215215
override_inheritance_no_such_method_test/10: MissingCompileTimeError
216216
override_inheritance_no_such_method_test/12: MissingCompileTimeError
217217
override_inheritance_no_such_method_test/13: MissingCompileTimeError
218+
partial_tearoff_instantiation_test/05: MissingCompileTimeError
219+
partial_tearoff_instantiation_test/06: MissingCompileTimeError
220+
partial_tearoff_instantiation_test/07: MissingCompileTimeError
221+
partial_tearoff_instantiation_test/08: MissingCompileTimeError
218222
redirecting_factory_default_values_test/01: MissingCompileTimeError # Fasta bug: Default values are not allowed on redirecting factory constructors.
219223
redirecting_factory_default_values_test/02: MissingCompileTimeError # Fasta bug: Default values are not allowed on redirecting factory constructors.
220224
regress_22976_test/*: CompileTimeError # Issue 31935

tests/language_2/language_2_vm.status

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1341,4 +1341,4 @@ invalid_type_argument_count_test/01: MissingCompileTimeError # Error only in str
13411341
invalid_type_argument_count_test/02: MissingCompileTimeError # Error only in strong mode
13421342
invalid_type_argument_count_test/03: MissingCompileTimeError # Error only in strong mode
13431343
invalid_type_argument_count_test/04: MissingCompileTimeError # Error only in strong mode
1344-
1344+
partial_tearoff_instantiation_test/none: CompiletimeError
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (c) 2018, 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+
typedef F1 = void Function<T>(T);
8+
typedef void F2<T>(T v);
9+
10+
dynamic defaultFLatest;
11+
12+
void defaultF<T>(T v) {
13+
defaultFLatest = v;
14+
}
15+
16+
class X1 {
17+
final F1 f;
18+
const X1({this.f: defaultF});
19+
}
20+
21+
class X2 {
22+
final F2 f;
23+
const X2({this.f: defaultF});
24+
}
25+
26+
class Y1 {
27+
F1 f;
28+
}
29+
30+
class Y2 {
31+
F2 f;
32+
}
33+
34+
dynamic foo() {
35+
if (defaultFLatest == -1) return -1;
36+
return "not -1";
37+
}
38+
39+
void main() {
40+
{
41+
var x = const X1();
42+
43+
// OK with implicit dynamic type argument.
44+
x.f("hello1");
45+
Expect.equals("hello1", defaultFLatest);
46+
47+
// OK with explicit dynamic type argument.
48+
x.f<dynamic>("hello2");
49+
Expect.equals("hello2", defaultFLatest);
50+
51+
// OK with correctly given argument type.
52+
x.f<String>("hello3");
53+
Expect.equals("hello3", defaultFLatest);
54+
55+
// OK with correctly given argument type.
56+
x.f<int>(42);
57+
Expect.equals(42, defaultFLatest);
58+
59+
// Not OK with incorrectly given argument type.
60+
x.f<int>("hello"); //# 01: compile-time error
61+
62+
// Not OK with incorrectly given argument type.
63+
x.f<int>(foo()); //# 02: runtime error
64+
65+
var y = new Y1();
66+
y.f = defaultF;
67+
68+
// OK with implicit dynamic type argument.
69+
y.f("hello4");
70+
Expect.equals("hello4", defaultFLatest);
71+
72+
// OK with explicit dynamic type argument.
73+
y.f<dynamic>("hello5");
74+
Expect.equals("hello5", defaultFLatest);
75+
76+
// OK with correctly given argument type.
77+
y.f<String>("hello6");
78+
Expect.equals("hello6", defaultFLatest);
79+
80+
// OK with correctly given argument type.
81+
y.f<int>(43);
82+
Expect.equals(43, defaultFLatest);
83+
84+
// Not OK with incorrectly given argument type.
85+
y.f<int>("hello"); //# 03: compile-time error
86+
87+
// Not OK with incorrectly given argument type.
88+
y.f<int>(foo()); //# 04: runtime error
89+
}
90+
{
91+
var x = const X2();
92+
93+
// OK with no type arguments.
94+
x.f("hello1");
95+
Expect.equals("hello1", defaultFLatest);
96+
97+
// Not OK with a type argument.
98+
x.f<dynamic>("hello2"); //# 05: compile-time error
99+
100+
// Not OK with a type argument.
101+
x.f<String>("hello3"); //# 06: compile-time error
102+
103+
var y = new Y2();
104+
y.f = defaultF;
105+
106+
// OK with no type argument.
107+
y.f("hello4");
108+
Expect.equals("hello4", defaultFLatest);
109+
110+
// Not OK with a type argument.
111+
y.f<dynamic>("hello5"); //# 07: compile-time error
112+
113+
// Not OK with a type argument.
114+
y.f<String>("hello6"); //# 08: compile-time error
115+
}
116+
}

0 commit comments

Comments
 (0)