diff --git a/pkg/dart2bytecode/lib/assembler.dart b/pkg/dart2bytecode/lib/assembler.dart index ceaa0b687ea..7404af915eb 100644 --- a/pkg/dart2bytecode/lib/assembler.dart +++ b/pkg/dart2bytecode/lib/assembler.dart @@ -729,9 +729,9 @@ class BytecodeAssembler { } @pragma('vm:prefer-inline') - void emitAllocateClosure(int rd) { + void emitAllocateClosure() { emitSourcePosition(); - _emitInstructionD(Opcode.kAllocateClosure, rd); + _emitInstruction0(Opcode.kAllocateClosure); } @pragma('vm:prefer-inline') diff --git a/pkg/dart2bytecode/lib/bytecode_generator.dart b/pkg/dart2bytecode/lib/bytecode_generator.dart index e7fff4403d8..fd8d97503e7 100644 --- a/pkg/dart2bytecode/lib/bytecode_generator.dart +++ b/pkg/dart2bytecode/lib/bytecode_generator.dart @@ -1621,11 +1621,11 @@ class BytecodeGenerator extends RecursiveVisitor { _genPrologue(node, node.function); _setupInitialContext(node.function); _emitFirstDebugCheck(node.function); + _genEqualsOperatorNullHandling(node); if (node is Procedure && node.isInstanceMember) { _checkArguments(node.function); } _initSuspendableFunction(node.function); - _genEqualsOperatorNullHandling(node); } // Generate additional code for 'operator ==' to handle nulls. @@ -2445,20 +2445,14 @@ class BytecodeGenerator extends RecursiveVisitor { void _genAllocateClosureInstance( TreeNode node, int closureFunctionIndex, FunctionNode function) { - asm.emitAllocateClosure(closureFunctionIndex); + asm.emitPushConstant(closureFunctionIndex); + asm.emitPush(locals.contextVarIndexInFrame); + _genPushInstantiatorTypeArguments(); + asm.emitAllocateClosure(); final int temp = locals.tempIndexInFrame(node); asm.emitStoreLocal(temp); - // TODO(alexmarkov): We need to fill _instantiator_type_arguments field - // only if function signature uses instantiator type arguments. - if (instantiatorTypeArguments != null) { - asm.emitPush(temp); - _genPushInstantiatorTypeArguments(); - asm.emitStoreFieldTOS( - cp.addInstanceField(closureInstantiatorTypeArguments)); - } - if (locals.hasFunctionTypeArgsVar) { asm.emitPush(temp); _genPushFunctionTypeArguments(); @@ -2471,14 +2465,6 @@ class BytecodeGenerator extends RecursiveVisitor { asm.emitPushConstant(cp.addEmptyTypeArguments()); asm.emitStoreFieldTOS(cp.addInstanceField(closureDelayedTypeArguments)); } - - asm.emitPush(temp); - asm.emitPushConstant(closureFunctionIndex); - asm.emitStoreFieldTOS(cp.addInstanceField(closureFunction)); - - asm.emitPush(temp); - asm.emitPush(locals.contextVarIndexInFrame); - asm.emitStoreFieldTOS(cp.addInstanceField(closureContext)); } void _genClosure(LocalFunction node, String name, FunctionNode function) { @@ -2782,28 +2768,24 @@ class BytecodeGenerator extends RecursiveVisitor { boundsCheckForPartialInstantiation, objectTable.getArgDescHandle(2), 2); asm.emitDrop1(); - assert(closureClass.typeParameters.isEmpty); - asm.emitAllocate(cp.addClass(closureClass)); + asm.emitPush(oldClosure); + asm.emitLoadFieldTOS(cp.addInstanceField(closureFunction)); + asm.emitPush(oldClosure); + asm.emitLoadFieldTOS(cp.addInstanceField(closureContext)); + asm.emitPush(oldClosure); + asm.emitLoadFieldTOS(cp.addInstanceField(closureInstantiatorTypeArguments)); + asm.emitAllocateClosure(); asm.emitStoreLocal(newClosure); asm.emitPush(typeArguments); asm.emitStoreFieldTOS(cp.addInstanceField(closureDelayedTypeArguments)); - // Copy the rest of the fields from old closure to a new closure. - final fieldsToCopy = [ - closureInstantiatorTypeArguments, - closureFunctionTypeArguments, - closureFunction, - closureContext, - ]; - - for (Field field in fieldsToCopy) { - final fieldOffsetCpIndex = cp.addInstanceField(field); - asm.emitPush(newClosure); - asm.emitPush(oldClosure); - asm.emitLoadFieldTOS(fieldOffsetCpIndex); - asm.emitStoreFieldTOS(fieldOffsetCpIndex); - } + asm.emitPush(newClosure); + asm.emitPush(oldClosure); + final closureFunctionTypeArgumentsCpIndex = + cp.addInstanceField(closureFunctionTypeArguments); + asm.emitLoadFieldTOS(closureFunctionTypeArgumentsCpIndex); + asm.emitStoreFieldTOS(closureFunctionTypeArgumentsCpIndex); asm.emitPush(newClosure); } diff --git a/pkg/dart2bytecode/lib/dbc.dart b/pkg/dart2bytecode/lib/dbc.dart index d549588aa09..f17d77f05d4 100644 --- a/pkg/dart2bytecode/lib/dbc.dart +++ b/pkg/dart2bytecode/lib/dbc.dart @@ -35,7 +35,7 @@ enum Opcode { kAllocateT, kCreateArrayTOS, kAllocateClosure, - kAllocateClosure_Wide, + kUnused03, // Context allocation and access. kAllocateContext, @@ -437,7 +437,7 @@ const Map BytecodeFormats = const { Opcode.kUncheckedDirectCall: const Format( Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]), Opcode.kAllocateClosure: const Format( - Encoding.kD, const [Operand.lit, Operand.none, Operand.none]), + Encoding.k0, const [Operand.none, Operand.none, Operand.none]), Opcode.kUncheckedClosureCall: const Format( Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]), Opcode.kUncheckedInterfaceCall: const Format( diff --git a/pkg/dart2bytecode/testcases/async.dart.expect b/pkg/dart2bytecode/testcases/async.dart.expect index c8b689ae53e..87f3cf534cd 100644 --- a/pkg/dart2bytecode/testcases/async.dart.expect +++ b/pkg/dart2bytecode/testcases/async.dart.expect @@ -11,14 +11,11 @@ Field 'asyncInFieldInitializer', type = FunctionType (dart:async::Future < dart: Bytecode { Entry 3 CheckStack 0 - AllocateClosure CP#0 - StoreLocal r2 - Push r2 PushConstant CP#0 - StoreFieldTOS CP#14 - Push r2 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r2 ReturnTOS } ConstantPool { @@ -36,8 +33,6 @@ ConstantPool { [11] = DirectCall 'dart:async::_SuspendState::_returnAsync', ArgDesc num-args 2, num-type-args 0, names [] [12] = Reserved [13] = EndClosureFunctionScope - [14] = InstanceField dart:core::_Closure::_function (field) - [15] = Reserved } Closure DART_SDK/pkg/dart2bytecode/testcases/async.dart::asyncInFieldInitializer (field)::'' async (dart:async::Future < dart:core::int > x) -> dart:async::Future < Null > ClosureCode { @@ -426,14 +421,11 @@ Bytecode { Push r0 PushInt 3 StoreContextVar 0, 1 - AllocateClosure CP#0 - StoreLocal r3 - Push r3 PushConstant CP#0 - StoreFieldTOS CP#15 - Push r3 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r3 PopLocal r2 Push r2 ReturnTOS @@ -454,8 +446,6 @@ ConstantPool { [12] = DirectCall 'dart:async::_SuspendState::_returnAsync', ArgDesc num-args 2, num-type-args 0, names [] [13] = Reserved [14] = EndClosureFunctionScope - [15] = InstanceField dart:core::_Closure::_function (field) - [16] = Reserved } Closure DART_SDK/pkg/dart2bytecode/testcases/async.dart::closure::'nested' async () -> dart:async::Future < dart:core::int > ClosureCode { diff --git a/pkg/dart2bytecode/testcases/closures.dart.expect b/pkg/dart2bytecode/testcases/closures.dart.expect index b69d4d6f482..875387816e2 100644 --- a/pkg/dart2bytecode/testcases/closures.dart.expect +++ b/pkg/dart2bytecode/testcases/closures.dart.expect @@ -19,20 +19,17 @@ Bytecode { Push r0 PushInt 5 StoreContextVar 0, 0 - AllocateClosure CP#0 - StoreLocal r3 - Push r3 PushConstant CP#0 - StoreFieldTOS CP#7 - Push r3 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r3 PopLocal r2 Push r2 StoreLocal r3 PushInt 3 Push r3 - UncheckedClosureCall CP#9, 2 + UncheckedClosureCall CP#7, 2 Drop1 Push r0 LoadContextVar 0, 0 @@ -46,9 +43,7 @@ ConstantPool { [4] = ObjectRef 'y' [5] = SubtypeTestCache [6] = EndClosureFunctionScope - [7] = InstanceField dart:core::_Closure::_function (field) - [8] = Reserved - [9] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [7] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] } Closure DART_SDK/pkg/dart2bytecode/testcases/closures.dart::simpleClosure::'' (dart:core::int y) -> Null ClosureCode { @@ -194,45 +189,36 @@ Function 'testPartialInstantiation', static, reflectable, debuggable Bytecode { Entry 7 CheckStack 0 - AllocateClosure CP#0 + PushConstant CP#0 + Push r0 + PushNull + AllocateClosure StoreLocal r3 Push r3 PushConstant CP#5 StoreFieldTOS CP#3 - Push r3 - PushConstant CP#0 - StoreFieldTOS CP#14 - Push r3 - Push r0 - StoreFieldTOS CP#1 PopLocal r2 Push r2 StoreLocal r3 - PushConstant CP#16 + PushConstant CP#14 StoreLocal r6 - DirectCall CP#17, 2 + DirectCall CP#15, 2 Drop1 - Allocate CP#19 + Push r3 + LoadFieldTOS CP#17 + Push r3 + LoadFieldTOS CP#1 + Push r3 + LoadFieldTOS CP#19 + AllocateClosure StoreLocal r5 Push r6 StoreFieldTOS CP#3 Push r5 Push r3 - LoadFieldTOS CP#20 - StoreFieldTOS CP#20 - Push r5 - Push r3 LoadFieldTOS CP#6 StoreFieldTOS CP#6 Push r5 - Push r3 - LoadFieldTOS CP#14 - StoreFieldTOS CP#14 - Push r5 - Push r3 - LoadFieldTOS CP#1 - StoreFieldTOS CP#1 - Push r5 PopLocal r4 Push r4 ReturnTOS @@ -252,14 +238,13 @@ ConstantPool { [11] = ObjectRef 't' [12] = SubtypeTestCache [13] = EndClosureFunctionScope - [14] = InstanceField dart:core::_Closure::_function (field) - [15] = Reserved - [16] = ObjectRef < dart:core::int > - [17] = DirectCall 'dart:_internal::_boundsCheckForPartialInstantiation', ArgDesc num-args 2, num-type-args 0, names [] + [14] = ObjectRef < dart:core::int > + [15] = DirectCall 'dart:_internal::_boundsCheckForPartialInstantiation', ArgDesc num-args 2, num-type-args 0, names [] + [16] = Reserved + [17] = InstanceField dart:core::_Closure::_function (field) [18] = Reserved - [19] = Class dart:core::_Closure - [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [21] = Reserved + [19] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) + [20] = Reserved } Closure DART_SDK/pkg/dart2bytecode/testcases/closures.dart::testPartialInstantiation::'foo' type-params <'T' extends dart:core::Object? (default dynamic)> (DART_SDK/pkg/dart2bytecode/testcases/closures.dart::testPartialInstantiation::Closure/0::TypeParam/0 t) -> void ClosureCode { @@ -526,34 +511,28 @@ Bytecode { Push r1 Push FP[-5] StoreContextVar 0, 0 - AllocateClosure CP#0 - StoreLocal r4 - Push r4 + PushConstant CP#0 + Push r1 Push FP[-5] LoadTypeArgumentsField CP#14 - StoreFieldTOS CP#30 + AllocateClosure + StoreLocal r4 Push r4 Push r0 StoreFieldTOS CP#6 Push r4 PushConstant CP#5 StoreFieldTOS CP#3 - Push r4 - PushConstant CP#0 - StoreFieldTOS CP#32 - Push r4 - Push r1 - StoreFieldTOS CP#1 PopLocal r3 - PushConstant CP#40 + PushConstant CP#36 Push r3 Push r3 - UncheckedClosureCall CP#37, 2 + UncheckedClosureCall CP#33, 2 Drop1 - PushConstant CP#41 + PushConstant CP#37 Push r3 Push r3 - UncheckedClosureCall CP#37, 2 + UncheckedClosureCall CP#33, 2 Drop1 PushNull ReturnTOS @@ -589,18 +568,14 @@ ConstantPool { [27] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/closures.dart::callWithArgs', ArgDesc num-args 0, num-type-args 8, names [] [28] = Reserved [29] = EndClosureFunctionScope - [30] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [31] = Reserved - [32] = InstanceField dart:core::_Closure::_function (field) - [33] = Reserved - [34] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [30] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [31] = EndClosureFunctionScope + [32] = ObjectRef < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C7, DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C8 > + [33] = ObjectRef ArgDesc num-args 1, num-type-args 2, names [] + [34] = ObjectRef < dart:core::List < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C7 >, dart:core::List < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C8 > > [35] = EndClosureFunctionScope - [36] = ObjectRef < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C7, DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C8 > - [37] = ObjectRef ArgDesc num-args 1, num-type-args 2, names [] - [38] = ObjectRef < dart:core::List < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C7 >, dart:core::List < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C8 > > - [39] = EndClosureFunctionScope - [40] = ObjectRef < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C5, DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C6 > - [41] = ObjectRef < dart:core::List < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C5 >, dart:core::List < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C6 > > + [36] = ObjectRef < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C5, DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C6 > + [37] = ObjectRef < dart:core::List < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C5 >, dart:core::List < DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C6 > > } Closure DART_SDK/pkg/dart2bytecode/testcases/closures.dart::A::foo::'nested1' type-params <'T5' extends dart:core::Object? (default dynamic), 'T6' extends dart:core::Object? (default dynamic)> () -> void ClosureCode { @@ -626,35 +601,29 @@ L2: PushInt 4 DirectCall CP#8, 4 PopLocal r0 - AllocateClosure CP#10 - StoreLocal r4 - Push r4 + PushConstant CP#10 + Push r1 Push r1 LoadContextVar 0, 0 LoadTypeArgumentsField CP#14 - StoreFieldTOS CP#30 + AllocateClosure + StoreLocal r4 Push r4 Push r0 StoreFieldTOS CP#6 Push r4 PushConstant CP#5 StoreFieldTOS CP#3 - Push r4 - PushConstant CP#10 - StoreFieldTOS CP#32 - Push r4 - Push r1 - StoreFieldTOS CP#1 PopLocal r3 - PushConstant CP#36 + PushConstant CP#32 Push r3 Push r3 - UncheckedClosureCall CP#37, 2 + UncheckedClosureCall CP#33, 2 Drop1 - PushConstant CP#38 + PushConstant CP#34 Push r3 Push r3 - UncheckedClosureCall CP#37, 2 + UncheckedClosureCall CP#33, 2 Drop1 PushNull ReturnTOS @@ -684,27 +653,21 @@ L2: PushInt 6 DirectCall CP#8, 4 PopLocal r0 - AllocateClosure CP#11 - StoreLocal r4 - Push r4 + PushConstant CP#11 + Push r1 Push r1 LoadContextVar 0, 0 LoadTypeArgumentsField CP#14 - StoreFieldTOS CP#30 + AllocateClosure + StoreLocal r4 Push r4 Push r0 StoreFieldTOS CP#6 - Push r4 - PushConstant CP#11 - StoreFieldTOS CP#32 - Push r4 - Push r1 - StoreFieldTOS CP#1 PopLocal r3 Push r3 StoreLocal r4 Push r4 - UncheckedClosureCall CP#34, 1 + UncheckedClosureCall CP#30, 1 Drop1 PushNull ReturnTOS @@ -813,54 +776,48 @@ Bytecode { Push r0 PushInt 3 StoreContextVar 0, 2 - AllocateClosure CP#0 - StoreLocal r4 - Push r4 PushConstant CP#0 - StoreFieldTOS CP#10 - Push r4 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r4 PopLocal r3 Push r3 StoreLocal r4 PushInt 10 Push r4 - UncheckedClosureCall CP#16, 2 + UncheckedClosureCall CP#14, 2 Drop1 Push r3 StoreLocal r4 PushInt 11 Push r4 - UncheckedClosureCall CP#16, 2 + UncheckedClosureCall CP#14, 2 Drop1 Push r2 - DirectCall CP#13, 1 + DirectCall CP#11, 1 Drop1 Push r0 LoadContextVar 0, 2 - DirectCall CP#13, 1 + DirectCall CP#11, 1 Drop1 Push r0 LoadContextVar 0, 1 - DirectCall CP#13, 1 + DirectCall CP#11, 1 Drop1 Push r0 PushInt 42 StoreContextVar 0, 3 - AllocateClosure CP#17 - StoreLocal r3 - Push r3 - PushConstant CP#17 - StoreFieldTOS CP#10 - Push r3 + PushConstant CP#15 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r3 PopLocal r2 Push r2 StoreLocal r3 Push r3 - UncheckedClosureCall CP#12, 1 + UncheckedClosureCall CP#10, 1 Drop1 PushNull ReturnTOS @@ -876,17 +833,15 @@ ConstantPool { [7] = InterfaceCall 'DART_SDK/pkg/dart2bytecode/testcases/closures.dart::B::get:foo', ArgDesc num-args 1, num-type-args 0, names [] [8] = Reserved [9] = EndClosureFunctionScope - [10] = InstanceField dart:core::_Closure::_function (field) - [11] = Reserved - [12] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [13] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names [] - [14] = Reserved - [15] = EndClosureFunctionScope - [16] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] - [17] = ClosureFunction 2 - [18] = InterfaceCall 'DART_SDK/pkg/dart2bytecode/testcases/closures.dart::B::set:foo', ArgDesc num-args 2, num-type-args 0, names [] - [19] = Reserved - [20] = EndClosureFunctionScope + [10] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [11] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names [] + [12] = Reserved + [13] = EndClosureFunctionScope + [14] = ObjectRef ArgDesc num-args 2, num-type-args 0, names [] + [15] = ClosureFunction 2 + [16] = InterfaceCall 'DART_SDK/pkg/dart2bytecode/testcases/closures.dart::B::set:foo', ArgDesc num-args 2, num-type-args 0, names [] + [17] = Reserved + [18] = EndClosureFunctionScope } Closure DART_SDK/pkg/dart2bytecode/testcases/closures.dart::B::topLevel::'' (dart:core::int y) -> Null ClosureCode { @@ -929,22 +884,19 @@ L1: Push r0 PushInt 4 StoreContextVar 1, 1 - AllocateClosure CP#6 - StoreLocal r2 - Push r2 PushConstant CP#6 - StoreFieldTOS CP#10 - Push r2 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r2 PopLocal r3 Push r3 Push r3 - UncheckedClosureCall CP#12, 1 + UncheckedClosureCall CP#10, 1 Drop1 Push r0 LoadContextVar 1, 1 - DirectCall CP#13, 1 + DirectCall CP#11, 1 Drop1 L2: PushNull @@ -990,7 +942,7 @@ ClosureCode { LoadContextVar 0, 0 Push r0 LoadContextVar 0, 3 - InterfaceCall CP#18, 2 + InterfaceCall CP#16, 2 Drop1 PushNull ReturnTOS @@ -1056,26 +1008,20 @@ L2: CompareIntLt JumpIfFalse L1 Push r2 - AllocateClosure CP#3 - StoreLocal r4 - Push r4 PushConstant CP#3 - StoreFieldTOS CP#7 - Push r4 Push r0 - StoreFieldTOS CP#4 - InstantiatedInterfaceCall CP#9, 2 + PushNull + AllocateClosure + StoreLocal r4 + InstantiatedInterfaceCall CP#7, 2 Drop1 Push r3 - AllocateClosure CP#12 - StoreLocal r4 - Push r4 - PushConstant CP#12 - StoreFieldTOS CP#7 - Push r4 + PushConstant CP#10 Push r0 - StoreFieldTOS CP#4 - InstantiatedInterfaceCall CP#9, 2 + PushNull + AllocateClosure + StoreLocal r4 + InstantiatedInterfaceCall CP#7, 2 Drop1 Push r0 CloneContext 1, 1 @@ -1108,16 +1054,14 @@ ConstantPool { [4] = InstanceField dart:core::_Closure::_context (field) [5] = Reserved [6] = EndClosureFunctionScope - [7] = InstanceField dart:core::_Closure::_function (field) + [7] = InstantiatedInterfaceCall 'dart:core::List::add', ArgDesc num-args 2, num-type-args 0, names [], receiver dart:core::List < dart:core::Function > [8] = Reserved - [9] = InstantiatedInterfaceCall 'dart:core::List::add', ArgDesc num-args 2, num-type-args 0, names [], receiver dart:core::List < dart:core::Function > - [10] = Reserved - [11] = Reserved - [12] = ClosureFunction 1 - [13] = Type dart:core::int - [14] = ObjectRef 'ii' - [15] = SubtypeTestCache - [16] = EndClosureFunctionScope + [9] = Reserved + [10] = ClosureFunction 1 + [11] = Type dart:core::int + [12] = ObjectRef 'ii' + [13] = SubtypeTestCache + [14] = EndClosureFunctionScope } Closure DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C::testForLoop::'' () -> dart:core::int ClosureCode { @@ -1144,11 +1088,11 @@ ClosureCode { CheckStack 0 JumpIfUnchecked L1 Push FP[-5] - PushConstant CP#13 + PushConstant CP#11 PushNull PushNull - PushConstant CP#14 - AssertAssignable 1, CP#15 + PushConstant CP#12 + AssertAssignable 1, CP#13 Drop1 L1: Push r0 @@ -1184,23 +1128,20 @@ L2: Push r2 InterfaceCall CP#4, 1 StoreContextVar 0, 0 - AllocateClosure CP#6 - StoreLocal r4 - Push r4 PushConstant CP#6 - StoreFieldTOS CP#10 - Push r4 Push r0 - StoreFieldTOS CP#7 + PushNull + AllocateClosure + StoreLocal r4 PopLocal r3 Push r3 StoreLocal r4 Push r4 - UncheckedClosureCall CP#12, 1 + UncheckedClosureCall CP#10, 1 Drop1 Push r0 LoadContextVar 0, 0 - DirectCall CP#13, 1 + DirectCall CP#11, 1 Drop1 Push r0 LoadContextParent @@ -1221,11 +1162,9 @@ ConstantPool { [7] = InstanceField dart:core::_Closure::_context (field) [8] = Reserved [9] = EndClosureFunctionScope - [10] = InstanceField dart:core::_Closure::_function (field) - [11] = Reserved - [12] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [13] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names [] - [14] = Reserved + [10] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [11] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names [] + [12] = Reserved } Closure DART_SDK/pkg/dart2bytecode/testcases/closures.dart::C::testForInLoop::'' () -> Null ClosureCode { @@ -1290,18 +1229,12 @@ Bytecode { AssertAssignable 0, CP#3 Drop1 L1: - AllocateClosure CP#4 - StoreLocal r2 - Push r2 + PushConstant CP#4 + Push r0 Push FP[-6] LoadTypeArgumentsField CP#1 - StoreFieldTOS CP#8 - Push r2 - PushConstant CP#4 - StoreFieldTOS CP#10 - Push r2 - Push r0 - StoreFieldTOS CP#5 + AllocateClosure + StoreLocal r2 ReturnTOS } Parameter flags: [2] @@ -1314,10 +1247,6 @@ ConstantPool { [5] = InstanceField dart:core::_Closure::_context (field) [6] = Reserved [7] = EndClosureFunctionScope - [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [9] = Reserved - [10] = InstanceField dart:core::_Closure::_function (field) - [11] = Reserved } Closure DART_SDK/pkg/dart2bytecode/testcases/closures.dart::D::foo::'' () -> DART_SDK/pkg/dart2bytecode/testcases/closures.dart::D::TypeParam/0 ClosureCode { @@ -1344,18 +1273,12 @@ Bytecode { Push r0 Push FP[-5] StoreContextVar 0, 0 - AllocateClosure CP#0 - StoreLocal r2 - Push r2 + PushConstant CP#0 + Push r0 Push FP[-5] LoadTypeArgumentsField CP#5 - StoreFieldTOS CP#6 - Push r2 - PushConstant CP#0 - StoreFieldTOS CP#8 - Push r2 - Push r0 - StoreFieldTOS CP#1 + AllocateClosure + StoreLocal r2 ReturnTOS } ConstantPool { @@ -1365,12 +1288,8 @@ ConstantPool { [3] = ClosureFunction 1 [4] = EndClosureFunctionScope [5] = TypeArgumentsField DART_SDK/pkg/dart2bytecode/testcases/closures.dart::D - [6] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field) - [7] = Reserved - [8] = InstanceField dart:core::_Closure::_function (field) - [9] = Reserved - [10] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [11] = EndClosureFunctionScope + [6] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [7] = EndClosureFunctionScope } Closure DART_SDK/pkg/dart2bytecode/testcases/closures.dart::D::bar::'' () -> Null ClosureCode { @@ -1379,23 +1298,17 @@ ClosureCode { LoadFieldTOS CP#1 PopLocal r0 CheckStack 0 - AllocateClosure CP#3 - StoreLocal r3 - Push r3 + PushConstant CP#3 + Push r0 Push r0 LoadContextVar 0, 0 LoadTypeArgumentsField CP#5 - StoreFieldTOS CP#6 - Push r3 - PushConstant CP#3 - StoreFieldTOS CP#8 - Push r3 - Push r0 - StoreFieldTOS CP#1 + AllocateClosure + StoreLocal r3 PopLocal r2 Push r2 Push r2 - UncheckedClosureCall CP#10, 1 + UncheckedClosureCall CP#6, 1 Drop1 PushNull ReturnTOS diff --git a/pkg/dart2bytecode/testcases/try_blocks.dart.expect b/pkg/dart2bytecode/testcases/try_blocks.dart.expect index ae3916a5bc6..c07bdbca4c3 100644 --- a/pkg/dart2bytecode/testcases/try_blocks.dart.expect +++ b/pkg/dart2bytecode/testcases/try_blocks.dart.expect @@ -215,18 +215,15 @@ Try #0 start: Push r0 PushInt 2 StoreContextVar 0, 1 - AllocateClosure CP#0 - StoreLocal r5 - Push r5 PushConstant CP#0 - StoreFieldTOS CP#8 - Push r5 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r5 PopLocal r4 Push r4 Push r4 - UncheckedClosureCall CP#10, 1 + UncheckedClosureCall CP#8, 1 Drop1 Push r0 LoadContextVar 0, 1 @@ -251,7 +248,7 @@ Try #0 handler: StoreLocal r5 Push r5 PushInt 0 - PushConstant CP#11 + PushConstant CP#9 StoreIndexedTOS Push r5 PushInt 1 @@ -259,24 +256,21 @@ Try #0 handler: StoreIndexedTOS Push r5 PushInt 2 - PushConstant CP#12 + PushConstant CP#10 StoreIndexedTOS Push r5 PushInt 3 Push r0 LoadContextVar 0, 2 StoreIndexedTOS - DirectCall CP#13, 1 + DirectCall CP#11, 1 DirectCall CP#4, 1 Drop1 - AllocateClosure CP#15 - StoreLocal r5 - Push r5 - PushConstant CP#15 - StoreFieldTOS CP#8 - Push r5 + PushConstant CP#13 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r5 PopLocal r6 Push r6 ReturnTOS @@ -288,7 +282,7 @@ L1: ReturnTOS } ExceptionsTable { - try-index 0, outer -1, start 20, end 66, handler 66, needs-stack-trace, types [CP#6] + try-index 0, outer -1, start 20, end 58, handler 58, needs-stack-trace, types [CP#6] } ConstantPool { [0] = ClosureFunction 0 @@ -299,21 +293,19 @@ ConstantPool { [5] = Reserved [6] = Type dart:core::Object [7] = EndClosureFunctionScope - [8] = InstanceField dart:core::_Closure::_function (field) - [9] = Reserved - [10] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [11] = ObjectRef 'caught ' - [12] = ObjectRef ' ' - [13] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names [] - [14] = Reserved - [15] = ClosureFunction 1 - [16] = ObjectRef 'danger bar' - [17] = Type dart:core::Error - [18] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names [] - [19] = Reserved - [20] = ObjectRef 'error ' - [21] = ObjectRef ', captured stack trace: ' - [22] = EndClosureFunctionScope + [8] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [9] = ObjectRef 'caught ' + [10] = ObjectRef ' ' + [11] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names [] + [12] = Reserved + [13] = ClosureFunction 1 + [14] = ObjectRef 'danger bar' + [15] = Type dart:core::Error + [16] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names [] + [17] = Reserved + [18] = ObjectRef 'error ' + [19] = ObjectRef ', captured stack trace: ' + [20] = EndClosureFunctionScope } Closure DART_SDK/pkg/dart2bytecode/testcases/try_blocks.dart::testTryCatch3::'foo' () -> void ClosureCode { @@ -361,7 +353,7 @@ ClosureCode { Push r0 PopLocal r2 Try #0 start: - PushConstant CP#16 + PushConstant CP#14 DirectCall CP#4, 1 Drop1 Jump L1 @@ -373,8 +365,8 @@ Try #0 handler: MoveSpecial exception, r2 MoveSpecial stackTrace, r3 Push r2 - PushConstant CP#17 - InterfaceCall CP#18, 2 + PushConstant CP#15 + InterfaceCall CP#16, 2 JumpIfFalse L2 Push r2 PopLocal r4 @@ -384,7 +376,7 @@ Try #0 handler: StoreLocal r5 Push r5 PushInt 0 - PushConstant CP#20 + PushConstant CP#18 StoreIndexedTOS Push r5 PushInt 1 @@ -392,14 +384,14 @@ Try #0 handler: StoreIndexedTOS Push r5 PushInt 2 - PushConstant CP#21 + PushConstant CP#19 StoreIndexedTOS Push r5 PushInt 3 Push r0 LoadContextVar 0, 2 StoreIndexedTOS - DirectCall CP#13, 1 + DirectCall CP#11, 1 DirectCall CP#4, 1 Drop1 Jump L1 @@ -598,18 +590,15 @@ Try #1 start: PushConstant CP#5 DirectCall CP#3, 1 Drop1 - AllocateClosure CP#6 - StoreLocal r8 - Push r8 PushConstant CP#6 - StoreFieldTOS CP#10 - Push r8 Push r0 - StoreFieldTOS CP#7 + PushNull + AllocateClosure + StoreLocal r8 PopLocal r7 Push r7 Push r7 - UncheckedClosureCall CP#12, 1 + UncheckedClosureCall CP#10, 1 Drop1 Jump L4 Try #1 end: @@ -619,7 +608,7 @@ Try #1 handler: PopLocal r0 MoveSpecial exception, r5 MoveSpecial stackTrace, r6 - PushConstant CP#14 + PushConstant CP#12 DirectCall CP#3, 1 Drop1 Push r5 @@ -628,7 +617,7 @@ Try #1 handler: L4: Push r5 PopLocal r0 - PushConstant CP#14 + PushConstant CP#12 DirectCall CP#3, 1 Drop1 Jump L5 @@ -639,7 +628,7 @@ Try #0 handler: PopLocal r0 MoveSpecial exception, r3 MoveSpecial stackTrace, r4 - PushConstant CP#16 + PushConstant CP#14 DirectCall CP#3, 1 Drop1 Push r3 @@ -648,12 +637,12 @@ Try #0 handler: L5: Push r3 PopLocal r0 - PushConstant CP#16 + PushConstant CP#14 DirectCall CP#3, 1 Drop1 Jump L2 L2: - PushConstant CP#17 + PushConstant CP#15 DirectCall CP#3, 1 Drop1 Jump L3 @@ -662,8 +651,8 @@ L3: ReturnTOS } ExceptionsTable { - try-index 0, outer -1, start 53, end 144, handler 144, needs-stack-trace, synthetic, types [CP#13] - try-index 1, outer 0, start 70, end 106, handler 106, needs-stack-trace, synthetic, types [CP#13] + try-index 0, outer -1, start 53, end 136, handler 136, needs-stack-trace, synthetic, types [CP#11] + try-index 1, outer 0, start 70, end 98, handler 98, needs-stack-trace, synthetic, types [CP#11] } ConstantPool { [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names [] @@ -676,14 +665,12 @@ ConstantPool { [7] = InstanceField dart:core::_Closure::_context (field) [8] = Reserved [9] = EndClosureFunctionScope - [10] = InstanceField dart:core::_Closure::_function (field) - [11] = Reserved - [12] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] - [13] = Type dynamic - [14] = ObjectRef 'finally 1' - [15] = ObjectRef 'after try 1' - [16] = ObjectRef 'finally 2' - [17] = ObjectRef 'case 2' + [10] = ObjectRef ArgDesc num-args 1, num-type-args 0, names [] + [11] = Type dynamic + [12] = ObjectRef 'finally 1' + [13] = ObjectRef 'after try 1' + [14] = ObjectRef 'finally 2' + [15] = ObjectRef 'case 2' } Closure DART_SDK/pkg/dart2bytecode/testcases/try_blocks.dart::testTryFinally2::'foo' () -> void ClosureCode { @@ -722,14 +709,11 @@ Bytecode { Push r0 PopLocal r3 Try #0 start: - AllocateClosure CP#0 - StoreLocal r5 - Push r5 PushConstant CP#0 - StoreFieldTOS CP#9 - Push r5 Push r0 - StoreFieldTOS CP#1 + PushNull + AllocateClosure + StoreLocal r5 PopLocal r2 Jump L1 Try #0 end: @@ -744,7 +728,7 @@ Try #0 handler: DirectCall CP#3, 1 Drop1 Push r2 - DynamicCall CP#11, 1 + DynamicCall CP#9, 1 Drop1 Push r3 Push r4 @@ -757,7 +741,7 @@ L1: DirectCall CP#3, 1 Drop1 Push r2 - DynamicCall CP#11, 1 + DynamicCall CP#9, 1 Drop1 Push r0 LoadContextParent @@ -766,7 +750,7 @@ L1: ReturnTOS } ExceptionsTable { - try-index 0, outer -1, start 23, end 45, handler 45, needs-stack-trace, synthetic, types [CP#6] + try-index 0, outer -1, start 23, end 37, handler 37, needs-stack-trace, synthetic, types [CP#6] } ConstantPool { [0] = ClosureFunction 0 @@ -778,10 +762,8 @@ ConstantPool { [6] = Type dynamic [7] = ObjectRef 'try 2' [8] = EndClosureFunctionScope - [9] = InstanceField dart:core::_Closure::_function (field) + [9] = DynamicCall 'call', ArgDesc num-args 1, num-type-args 0, names [] [10] = Reserved - [11] = DynamicCall 'call', ArgDesc num-args 1, num-type-args 0, names [] - [12] = Reserved } Closure DART_SDK/pkg/dart2bytecode/testcases/try_blocks.dart::testTryFinally3::'' () -> dart:core::int ClosureCode { diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc index 6b3229f7e60..1f65699a413 100644 --- a/runtime/vm/compiler/assembler/disassembler_kbc.cc +++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc @@ -251,8 +251,6 @@ static intptr_t GetConstantPoolIndex(const KBCInstr* instr) { case KernelBytecode::kLoadStatic_Wide: case KernelBytecode::kAllocate: case KernelBytecode::kAllocate_Wide: - case KernelBytecode::kAllocateClosure: - case KernelBytecode::kAllocateClosure_Wide: case KernelBytecode::kInstantiateType: case KernelBytecode::kInstantiateType_Wide: case KernelBytecode::kDirectCall: diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h index 81ff2ab1494..24056532a7e 100644 --- a/runtime/vm/constants_kbc.h +++ b/runtime/vm/constants_kbc.h @@ -445,9 +445,16 @@ namespace dart { // Receiver and argument should have static type double. // Check SP[-1] and SP[0] for null; push SP[-1] SP[0] ? true : false. // -// - AllocateClosure D +// - AllocateClosure // -// Allocate closure object for closure function ConstantPool[D]. +// Allocate closure object and initialize its fields: +// +// SP[-2] closure function +// SP[-1] context +// SP[0] instantiator type arguments +// +// These arguments are consumed from the stack and allocated +// object is pushed. // // BYTECODE LIST FORMAT // @@ -494,8 +501,8 @@ namespace dart { V(Allocate_Wide, D, WIDE, lit, ___, ___) \ V(AllocateT, 0, ORDN, ___, ___, ___) \ V(CreateArrayTOS, 0, ORDN, ___, ___, ___) \ - V(AllocateClosure, D, ORDN, lit, ___, ___) \ - V(AllocateClosure_Wide, D, WIDE, lit, ___, ___) \ + V(AllocateClosure, 0, ORDN, ___, ___, ___) \ + V(Unused03, 0, RESV, ___, ___, ___) \ V(AllocateContext, A_E, ORDN, num, num, ___) \ V(AllocateContext_Wide, A_E, WIDE, num, num, ___) \ V(CloneContext, A_E, ORDN, num, num, ___) \ diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc index 093208a0e57..28357c38d80 100644 --- a/runtime/vm/interpreter.cc +++ b/runtime/vm/interpreter.cc @@ -2468,17 +2468,10 @@ SwitchDispatch: BYTECODE(AssertAssignable, A_E); // Stack: instance, type, instantiator type args, function type args, name ObjectPtr* args = SP - 4; - const bool may_be_smi = (rA == 1); - const bool is_smi = - ((static_cast(args[0]) & kSmiTagMask) == kSmiTag); - const bool smi_ok = is_smi && may_be_smi; - if (!smi_ok && (args[0] != null_value)) { - SubtypeTestCachePtr cache = - static_cast(LOAD_CONSTANT(rE)); + SubtypeTestCachePtr cache = SubtypeTestCache::RawCast(LOAD_CONSTANT(rE)); - if (!AssertAssignable(thread, pc, FP, SP, args, cache)) { - HANDLE_EXCEPTION; - } + if (!AssertAssignable(thread, pc, FP, SP, args, cache)) { + HANDLE_EXCEPTION; } SP -= 4; // Instance remains on stack. @@ -3049,17 +3042,28 @@ SwitchDispatch: } { - BYTECODE(AllocateClosure, D); + BYTECODE(AllocateClosure, 0); ++SP; if (!AllocateClosure(thread, pc, FP, SP)) { HANDLE_EXCEPTION; } - FunctionPtr function = Function::RawCast(LOAD_CONSTANT(rD)); - ASSERT(Function::KindOf(function) == UntaggedFunction::kClosureFunction); ClosurePtr closure = Closure::RawCast(SP[0]); + FunctionPtr function = Function::RawCast(SP[-3]); + ObjectPtr context = SP[-2]; + TypeArgumentsPtr instantiator_type_arguments = + TypeArguments::RawCast(SP[-1]); + + ASSERT((Function::KindOf(function) == UntaggedFunction::kClosureFunction) || + (Function::KindOf(function) == + UntaggedFunction::kImplicitClosureFunction)); closure->untag()->set_function(function); ONLY_IN_PRECOMPILED(closure->untag()->entry_point_ = function->untag()->entry_point_); + closure->untag()->set_context(context); + closure->untag()->set_instantiator_type_arguments( + instantiator_type_arguments); + SP -= 3; + SP[0] = closure; DISPATCH(); } diff --git a/utils/dynamic_module_runner/dynamic_interface.yaml b/utils/dynamic_module_runner/dynamic_interface.yaml index eff78dfd895..828760baa5a 100644 --- a/utils/dynamic_module_runner/dynamic_interface.yaml +++ b/utils/dynamic_module_runner/dynamic_interface.yaml @@ -16,6 +16,11 @@ callable: - library: 'dart:core' class: '_Enum' member: '' + - library: 'dart:core' + class: '_InvocationMirror' + - library: 'dart:core' + class: '_InvocationMirror' + member: '_withType' - library: 'dart:core' class: '_GrowableList' - library: 'dart:core'