[vm/bytecode] Add eager bounds checks to partial instantiations in bytecode
This is the follow-up to
https://github.com/dart-lang/sdk/commit/dbe868de02d3b8e156c963d39f26fd95b6683e9b
Similarly to StreamingFlowGraphBuilder::BuildPartialTearoffInstantiation,
bytecode generator adds _boundsCheckForPartialInstantiation calls
to partial instantiations of tear-offs.
Fixes language_2/partial_instantiation_eager_bounds_check_test in bytecode mode.
Change-Id: I2daf1902aa3df99133b2a25f1413e1bac53b6c30
Reviewed-on: https://dart-review.googlesource.com/72549
Reviewed-by: RĂ©gis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 62fa462..1b228dd 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -239,6 +239,11 @@
Procedure get prependTypeArguments => _prependTypeArguments ??=
libraryIndex.getTopLevelMember('dart:_internal', '_prependTypeArguments');
+ Procedure _boundsCheckForPartialInstantiation;
+ Procedure get boundsCheckForPartialInstantiation =>
+ _boundsCheckForPartialInstantiation ??= libraryIndex.getTopLevelMember(
+ 'dart:_internal', '_boundsCheckForPartialInstantiation');
+
Procedure _futureValue;
Procedure get futureValue =>
_futureValue ??= libraryIndex.getMember('dart:async', 'Future', 'value');
@@ -1409,15 +1414,23 @@
visitInstantiation(Instantiation node) {
final int oldClosure = locals.tempIndexInFrame(node, tempIndex: 0);
final int newClosure = locals.tempIndexInFrame(node, tempIndex: 1);
+ final int typeArguments = locals.tempIndexInFrame(node, tempIndex: 2);
node.expression.accept(this);
- asm.emitPopLocal(oldClosure);
+ asm.emitStoreLocal(oldClosure);
+
+ _genTypeArguments(node.typeArguments);
+ asm.emitStoreLocal(typeArguments);
+
+ _genStaticCall(
+ boundsCheckForPartialInstantiation, new ConstantArgDesc(2), 2);
+ asm.emitDrop1();
assert(closureClass.typeParameters.isEmpty);
asm.emitAllocate(cp.add(new ConstantClass(closureClass)));
asm.emitStoreLocal(newClosure);
- _genTypeArguments(node.typeArguments);
+ asm.emitPush(typeArguments);
asm.emitStoreFieldTOS(
cp.add(new ConstantInstanceField(closureDelayedTypeArguments)));
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index 45d8351..a92c969 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -1136,6 +1136,6 @@
@override
visitInstantiation(Instantiation node) {
- _visit(node, temps: 2);
+ _visit(node, temps: 3);
}
}
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index f125b99..eb11001 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -1493,7 +1493,7 @@
}
[@vm.bytecode=
Bytecode {
- Entry 6
+ Entry 7
CheckStack
Allocate CP#17
StoreLocal r3
@@ -1514,10 +1514,15 @@
StoreFieldTOS CP#1
PopLocal r2
Push r2
- PopLocal r3
+ StoreLocal r3
+ PushConstant CP#22
+ StoreLocal r6
+ PushConstant CP#24
+ IndirectStaticCall 2, CP#23
+ Drop1
Allocate CP#17
StoreLocal r5
- PushConstant CP#22
+ Push r6
StoreFieldTOS CP#3
Push r5
Push r3
@@ -1566,6 +1571,8 @@
[20] = InstanceField dart.core::_Closure::_function
[21] = Reserved
[22] = TypeArgs [dart.core::int]
+ [23] = ArgDesc num-args 2, num-type-args 0, names []
+ [24] = StaticICData target 'dart._internal::_boundsCheckForPartialInstantiation', arg-desc CP#23
}
Closure CP#0 {
EntryFixed 2, 3