[vm] Remove irregular type arguments parameter from factories
In the VM, factory constructors always had an extra "type arguments" parameter, even if class is not generic. Factory constructor bodies were using class type parameters instead of function type parameters. This results in extra code when calling non-generic factories which is slightly inefficient in terms of code size and performance. Also, it creates an additional complexity throughout the system as factories should be special cased in many places. This change removes artificial "type arguments" parameter, treating factory constructors basically as static methods. This matches kernel AST representation. TEST=ci Change-Id: I957583cb2ce9a3c408699880a04036e06b01dd31 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/501762 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
66b54232ee
commit
6195ea86bc
@@ -949,9 +949,7 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
void _genExternalCall(Member node) {
|
||||
final function = node.function!;
|
||||
|
||||
if (locals.hasFactoryTypeArgsVar) {
|
||||
asm.emitPush(locals.getVarIndexInFrame(locals.factoryTypeArgsVar));
|
||||
} else if (locals.hasFunctionTypeArgsVar) {
|
||||
if (locals.hasFunctionTypeArgsVar) {
|
||||
asm.emitPush(locals.functionTypeArgsVarIndexInFrame);
|
||||
}
|
||||
if (locals.hasReceiver) {
|
||||
@@ -1483,23 +1481,19 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
Member target,
|
||||
Arguments args, {
|
||||
bool hasReceiver = false,
|
||||
bool isFactory = false,
|
||||
bool isUnchecked = false,
|
||||
TreeNode? node,
|
||||
}) {
|
||||
final argDesc = objectTable.getArgDescHandleByArguments(
|
||||
args,
|
||||
hasReceiver: hasReceiver,
|
||||
isFactory: isFactory,
|
||||
);
|
||||
|
||||
int totalArgCount = args.positional.length + args.named.length;
|
||||
if (hasReceiver) {
|
||||
totalArgCount++;
|
||||
}
|
||||
if (args.types.isNotEmpty || isFactory) {
|
||||
// VM needs type arguments for every invocation of a factory constructor.
|
||||
// TODO(alexmarkov): Clean this up.
|
||||
if (args.types.isNotEmpty) {
|
||||
totalArgCount++;
|
||||
}
|
||||
|
||||
@@ -1573,17 +1567,9 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
|
||||
void _genPushInstantiatorTypeArguments() {
|
||||
if (instantiatorTypeArguments != null) {
|
||||
if (locals.hasFactoryTypeArgsVar) {
|
||||
assert(
|
||||
enclosingMember is Procedure &&
|
||||
(enclosingMember as Procedure).isFactory,
|
||||
);
|
||||
_genLoadVar(locals.factoryTypeArgsVar);
|
||||
} else {
|
||||
_genPushReceiver();
|
||||
final int cpIndex = cp.addTypeArgumentsField(enclosingClass!);
|
||||
asm.emitLoadTypeArgumentsField(cpIndex);
|
||||
}
|
||||
_genPushReceiver();
|
||||
final int cpIndex = cp.addTypeArgumentsField(enclosingClass!);
|
||||
asm.emitLoadTypeArgumentsField(cpIndex);
|
||||
} else {
|
||||
asm.emitPushNull();
|
||||
}
|
||||
@@ -1844,22 +1830,15 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
isClosure = false;
|
||||
hasErrors = false;
|
||||
staticTypeContext.enterMember(node);
|
||||
final isFactory = node is Procedure && node.isFactory;
|
||||
if (node.isInstanceMember || node is Constructor || isFactory) {
|
||||
if (node.isInstanceMember || node is Constructor) {
|
||||
if (enclosingClass!.typeParameters.isNotEmpty) {
|
||||
final classTypeParameters = this.classTypeParameters =
|
||||
new Set<TypeParameter>.from(enclosingClass.typeParameters);
|
||||
// Treat type arguments of factory constructors as class
|
||||
// type parameters.
|
||||
if (isFactory) {
|
||||
classTypeParameters.addAll(node.function.typeParameters);
|
||||
}
|
||||
this.classTypeParameters = new Set<TypeParameter>.from(
|
||||
enclosingClass.typeParameters,
|
||||
);
|
||||
}
|
||||
if (hasInstantiatorTypeArguments(enclosingClass)) {
|
||||
final typeParameters = getTypeParameterTypes(
|
||||
isFactory
|
||||
? node.function.typeParameters
|
||||
: enclosingClass.typeParameters,
|
||||
enclosingClass.typeParameters,
|
||||
);
|
||||
instantiatorTypeArguments = flattenInstantiatorTypeArguments(
|
||||
enclosingClass,
|
||||
@@ -2196,8 +2175,6 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
}
|
||||
|
||||
if (locals.hasFunctionTypeArgsVar && function!.typeParameters.isNotEmpty) {
|
||||
assert(!(node is Procedure && node.isFactory));
|
||||
|
||||
Label done = new Label();
|
||||
|
||||
if (isClosure) {
|
||||
@@ -2353,9 +2330,6 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
if (locals.hasCapturedParameters) {
|
||||
// Copy captured parameters to their respective locations in the context.
|
||||
if (!isClosure) {
|
||||
if (locals.hasFactoryTypeArgsVar) {
|
||||
_copyParamIfCaptured(locals.factoryTypeArgsVar);
|
||||
}
|
||||
if (locals.hasCapturedReceiverVar) {
|
||||
_genPushContextForVariable(locals.capturedReceiverVar);
|
||||
asm.emitPush(locals.getVarIndexInFrame(locals.receiverVar));
|
||||
@@ -3385,11 +3359,8 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
// _GrowableList._literal is a factory constructor.
|
||||
// Type arguments passed to a factory constructor are counted as a normal
|
||||
// argument and not counted in number of type arguments.
|
||||
assert(growableListLiteral.isFactory);
|
||||
_genDirectCall(growableListLiteral, objectTable.getArgDescHandle(2), 2);
|
||||
_genDirectCall(growableListLiteral, objectTable.getArgDescHandle(1, 1), 2);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -3451,11 +3422,8 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
// Map._fromLiteral is a factory constructor.
|
||||
// Type arguments passed to a factory constructor are counted as a normal
|
||||
// argument and not counted in number of type arguments.
|
||||
assert(mapFromLiteral.isFactory);
|
||||
_genDirectCall(mapFromLiteral, objectTable.getArgDescHandle(2), 2);
|
||||
_genDirectCall(mapFromLiteral, objectTable.getArgDescHandle(1, 2), 2);
|
||||
}
|
||||
|
||||
void _genMethodInvocationUsingSpecializedBytecode(
|
||||
@@ -4025,28 +3993,8 @@ class BytecodeGenerator extends RecursiveVisitor {
|
||||
_generateFfiCall(args.positional.single);
|
||||
return;
|
||||
}
|
||||
if (target.isFactory) {
|
||||
final constructedClass = target.enclosingClass!;
|
||||
if (hasInstantiatorTypeArguments(constructedClass)) {
|
||||
_genTypeArguments(args.types, instantiatingClass: constructedClass);
|
||||
} else {
|
||||
assert(args.types.isEmpty);
|
||||
// VM needs type arguments for every invocation of a factory
|
||||
// constructor. TODO(alexmarkov): Clean this up.
|
||||
asm.emitPushNull();
|
||||
}
|
||||
args = new Arguments(
|
||||
node.arguments.positional,
|
||||
named: node.arguments.named,
|
||||
)..parent = node;
|
||||
}
|
||||
_genArguments(null, args);
|
||||
_genDirectCallWithArgs(
|
||||
target,
|
||||
args,
|
||||
isFactory: target.isFactory,
|
||||
node: node,
|
||||
);
|
||||
_genDirectCallWithArgs(target, args, node: node);
|
||||
if (target == debugger) {
|
||||
// The debugger needs a pause for the current source position right after
|
||||
// stepping out from the debugger function.
|
||||
|
||||
@@ -692,17 +692,9 @@ class ConstantPool {
|
||||
),
|
||||
);
|
||||
|
||||
int addArgDescByArguments(
|
||||
Arguments args, {
|
||||
bool hasReceiver = false,
|
||||
bool isFactory = false,
|
||||
}) => _add(
|
||||
int addArgDescByArguments(Arguments args, {bool hasReceiver = false}) => _add(
|
||||
new ConstantObjectRef(
|
||||
objectTable.getArgDescHandleByArguments(
|
||||
args,
|
||||
hasReceiver: hasReceiver,
|
||||
isFactory: isFactory,
|
||||
),
|
||||
objectTable.getArgDescHandleByArguments(args, hasReceiver: hasReceiver),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -120,12 +120,6 @@ class LocalVariables {
|
||||
|
||||
bool get hasFunctionTypeArgsVar => _currentFrame.functionTypeArgsVar != null;
|
||||
|
||||
VariableDeclaration get factoryTypeArgsVar =>
|
||||
_currentFrame.factoryTypeArgsVar ??
|
||||
(throw 'FactoryTypeArgs variable is not declared in ${_currentFrame.function}');
|
||||
|
||||
bool get hasFactoryTypeArgsVar => _currentFrame.factoryTypeArgsVar != null;
|
||||
|
||||
VariableDeclaration get receiverVar =>
|
||||
_currentFrame.receiverVar ??
|
||||
(throw 'Receiver variable is not declared in ${_currentFrame.function}');
|
||||
@@ -243,7 +237,6 @@ class Frame {
|
||||
VariableDeclaration? receiverVar;
|
||||
VariableDeclaration? capturedReceiverVar;
|
||||
VariableDeclaration? functionTypeArgsVar;
|
||||
VariableDeclaration? factoryTypeArgsVar;
|
||||
VariableDeclaration? closureVar;
|
||||
VariableDeclaration? contextVar;
|
||||
VariableDeclaration? scratchVar;
|
||||
@@ -364,29 +357,15 @@ class _ScopeBuilder extends RecursiveVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
if (node is Procedure && node.isFactory) {
|
||||
assert(_currentFrame.parent == null);
|
||||
_currentFrame.numTypeArguments = 0;
|
||||
final factoryTypeArgsVar = _currentFrame.factoryTypeArgsVar =
|
||||
VariableDeclaration(':type_arguments');
|
||||
_declareVariable(factoryTypeArgsVar);
|
||||
} else {
|
||||
_currentFrame.numTypeArguments =
|
||||
(_currentFrame.parent?.numTypeArguments ?? 0) +
|
||||
function.typeParameters.length;
|
||||
_currentFrame.numTypeArguments =
|
||||
(_currentFrame.parent?.numTypeArguments ?? 0) +
|
||||
function.typeParameters.length;
|
||||
|
||||
if (_currentFrame.numTypeArguments > 0) {
|
||||
final functionTypeArgsVar = _currentFrame.functionTypeArgsVar =
|
||||
VariableDeclaration(':function_type_arguments_var')
|
||||
..fileOffset = function.fileOffset;
|
||||
_declareVariable(functionTypeArgsVar);
|
||||
}
|
||||
|
||||
final parentFactoryTypeArgsVar =
|
||||
_currentFrame.parent?.factoryTypeArgsVar;
|
||||
if (parentFactoryTypeArgsVar != null) {
|
||||
_currentFrame.factoryTypeArgsVar = parentFactoryTypeArgsVar;
|
||||
}
|
||||
if (_currentFrame.numTypeArguments > 0) {
|
||||
final functionTypeArgsVar = _currentFrame.functionTypeArgsVar =
|
||||
VariableDeclaration(':function_type_arguments_var')
|
||||
..fileOffset = function.fileOffset;
|
||||
_declareVariable(functionTypeArgsVar);
|
||||
}
|
||||
|
||||
if (_hasReceiverParameter(node)) {
|
||||
@@ -625,8 +604,6 @@ class _ScopeBuilder extends RecursiveVisitor {
|
||||
var parent = node.parameter.declaration;
|
||||
if (parent is Class) {
|
||||
_useThis();
|
||||
} else if (parent is Procedure && parent.isFactory) {
|
||||
_useVariable(_currentFrame.factoryTypeArgsVar!);
|
||||
}
|
||||
node.visitChildren(this);
|
||||
}
|
||||
@@ -946,7 +923,6 @@ class _Allocator extends RecursiveVisitor {
|
||||
}
|
||||
|
||||
void _allocateParameters(TreeNode node, FunctionNode function) {
|
||||
final bool isFactory = node is Procedure && node.isFactory;
|
||||
final bool hasReceiver = _hasReceiverParameter(node);
|
||||
final bool hasClosureArg =
|
||||
node is FunctionDeclaration || node is FunctionExpression;
|
||||
@@ -954,7 +930,6 @@ class _Allocator extends RecursiveVisitor {
|
||||
_currentFrame.numParameters =
|
||||
function.positionalParameters.length +
|
||||
function.namedParameters.length +
|
||||
(isFactory ? 1 : 0) +
|
||||
(hasReceiver ? 1 : 0) +
|
||||
(hasClosureArg ? 1 : 0);
|
||||
|
||||
@@ -964,15 +939,11 @@ class _Allocator extends RecursiveVisitor {
|
||||
function.namedParameters.isNotEmpty;
|
||||
|
||||
_currentFrame.hasCapturedParameters =
|
||||
(isFactory && locals.isCaptured(_currentFrame.factoryTypeArgsVar!)) ||
|
||||
(hasReceiver && _currentFrame.capturedReceiverVar != null) ||
|
||||
function.positionalParameters.any(locals.isCaptured) ||
|
||||
function.namedParameters.any(locals.isCaptured);
|
||||
|
||||
int count = 0;
|
||||
if (isFactory) {
|
||||
_allocateParameter(_currentFrame.factoryTypeArgsVar!, count++);
|
||||
}
|
||||
if (hasReceiver) {
|
||||
assert(!locals.isCaptured(_currentFrame.receiverVar!));
|
||||
_allocateParameter(_currentFrame.receiverVar!, count++);
|
||||
|
||||
@@ -1920,7 +1920,6 @@ class ObjectTable implements ObjectWriter, ObjectReader {
|
||||
ObjectHandle getArgDescHandleByArguments(
|
||||
Arguments args, {
|
||||
bool hasReceiver = false,
|
||||
bool isFactory = false,
|
||||
}) {
|
||||
List<_PublicNameHandle> argNames = const <_PublicNameHandle>[];
|
||||
final namedArguments = args.named;
|
||||
@@ -1931,15 +1930,8 @@ class ObjectTable implements ObjectWriter, ObjectReader {
|
||||
);
|
||||
}
|
||||
final int numArguments =
|
||||
args.positional.length +
|
||||
args.named.length +
|
||||
(hasReceiver ? 1 : 0) +
|
||||
// VM expects that type arguments vector passed to a factory
|
||||
// constructor is counted in numArguments, and not counted in
|
||||
// numTypeArgs.
|
||||
// TODO(alexmarkov): Clean this up.
|
||||
(isFactory ? 1 : 0);
|
||||
final int numTypeArguments = isFactory ? 0 : args.types.length;
|
||||
args.positional.length + args.named.length + (hasReceiver ? 1 : 0);
|
||||
final int numTypeArguments = args.types.length;
|
||||
return getOrAddObject(
|
||||
new _ArgDescHandle(numArguments, numTypeArguments, argNames),
|
||||
);
|
||||
|
||||
@@ -122,7 +122,7 @@ ConstantPool {
|
||||
[6] = Type DART_SDK/pkg/dart2bytecode/testcases/closures.dart::callWithArgs::TypeParam/5
|
||||
[7] = Type DART_SDK/pkg/dart2bytecode/testcases/closures.dart::callWithArgs::TypeParam/6
|
||||
[8] = Type DART_SDK/pkg/dart2bytecode/testcases/closures.dart::callWithArgs::TypeParam/7
|
||||
[9] = DirectCall 'dart:core::_GrowableList::_literal8 (constructor)', ArgDesc num-args 9, num-type-args 0, names []
|
||||
[9] = DirectCall 'dart:core::_GrowableList::_literal8 (constructor)', ArgDesc num-args 8, num-type-args 1, names []
|
||||
[10] = Reserved
|
||||
[11] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[12] = Reserved
|
||||
@@ -531,7 +531,7 @@ ConstantPool {
|
||||
[13] = Type DART_SDK/pkg/dart2bytecode/testcases/closures.dart::A::foo::Closure/0::TypeParam/1
|
||||
[14] = Type DART_SDK/pkg/dart2bytecode/testcases/closures.dart::A::foo::Closure/1::TypeParam/0
|
||||
[15] = Type DART_SDK/pkg/dart2bytecode/testcases/closures.dart::A::foo::Closure/1::TypeParam/1
|
||||
[16] = DirectCall 'dart:core::_GrowableList::_literal8 (constructor)', ArgDesc num-args 9, num-type-args 0, names []
|
||||
[16] = DirectCall 'dart:core::_GrowableList::_literal8 (constructor)', ArgDesc num-args 8, num-type-args 1, names []
|
||||
[17] = Reserved
|
||||
[18] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[19] = Reserved
|
||||
@@ -1035,7 +1035,7 @@ L1:
|
||||
}
|
||||
ConstantPool {
|
||||
[0] = ObjectRef < dart:core::Function >
|
||||
[1] = DirectCall 'dart:core::_GrowableList:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
|
||||
[1] = DirectCall 'dart:core::_GrowableList:: (constructor)', ArgDesc num-args 1, num-type-args 1, names []
|
||||
[2] = Reserved
|
||||
[3] = ClosureFunction 0
|
||||
[4] = EndClosureFunctionScope
|
||||
|
||||
@@ -46,7 +46,7 @@ Bytecode {
|
||||
ConstantPool {
|
||||
[0] = ObjectRef < dart:ffi::NativeFunction < FunctionType () -> dart:ffi::Void > >
|
||||
[1] = ObjectRef const 3735928559
|
||||
[2] = DirectCall 'dart:ffi::Pointer::fromAddress (constructor)', ArgDesc num-args 2, num-type-args 0, names []
|
||||
[2] = DirectCall 'dart:ffi::Pointer::fromAddress (constructor)', ArgDesc num-args 1, num-type-args 1, names []
|
||||
[3] = Reserved
|
||||
[4] = ClosureFunction 0
|
||||
[5] = FfiCall
|
||||
@@ -107,7 +107,7 @@ Bytecode {
|
||||
ConstantPool {
|
||||
[0] = ObjectRef < dart:ffi::NativeFunction < FunctionType (dart:ffi::Int64) -> dart:ffi::Int32 > >
|
||||
[1] = ObjectRef const 3735928559
|
||||
[2] = DirectCall 'dart:ffi::Pointer::fromAddress (constructor)', ArgDesc num-args 2, num-type-args 0, names []
|
||||
[2] = DirectCall 'dart:ffi::Pointer::fromAddress (constructor)', ArgDesc num-args 1, num-type-args 1, names []
|
||||
[3] = Reserved
|
||||
[4] = ClosureFunction 0
|
||||
[5] = Type dart:core::int
|
||||
|
||||
@@ -115,7 +115,7 @@ Bytecode {
|
||||
}
|
||||
ConstantPool {
|
||||
[0] = ObjectRef < dart:core::int, dart:core::List < dart:core::String > >
|
||||
[1] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::G::testFactory (constructor)', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[1] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::G::testFactory (constructor)', ArgDesc num-args 0, num-type-args 2, names []
|
||||
[2] = Reserved
|
||||
}
|
||||
|
||||
@@ -127,20 +127,18 @@ Function 'foo5', static, reflectable, debuggable
|
||||
Bytecode {
|
||||
Entry 0
|
||||
CheckStack 0
|
||||
PushNull
|
||||
DirectCall CP#0, 1
|
||||
DirectCall CP#0, 0
|
||||
Drop1
|
||||
PushNull
|
||||
PushInt 42
|
||||
DirectCall CP#2, 2
|
||||
DirectCall CP#2, 1
|
||||
Drop1
|
||||
PushNull
|
||||
ReturnTOS
|
||||
}
|
||||
ConstantPool {
|
||||
[0] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::I::testFactory2 (constructor)', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[0] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::I::testFactory2 (constructor)', ArgDesc num-args 0, num-type-args 0, names []
|
||||
[1] = Reserved
|
||||
[2] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::I::testFactory2 (constructor)', ArgDesc num-args 2, num-type-args 0, names ['param']
|
||||
[2] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::I::testFactory2 (constructor)', ArgDesc num-args 1, num-type-args 0, names ['param']
|
||||
[3] = Reserved
|
||||
}
|
||||
|
||||
@@ -158,7 +156,7 @@ Bytecode {
|
||||
}
|
||||
ConstantPool {
|
||||
[0] = ObjectRef < dart:core::String >
|
||||
[1] = DirectCall 'dart:core::_List::empty (constructor)', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[1] = DirectCall 'dart:core::_List::empty (constructor)', ArgDesc num-args 0, num-type-args 1, names []
|
||||
[2] = Reserved
|
||||
}
|
||||
|
||||
@@ -178,7 +176,7 @@ Bytecode {
|
||||
}
|
||||
ConstantPool {
|
||||
[0] = ObjectRef < dart:core::int >
|
||||
[1] = DirectCall 'dart:core::_List::filled (constructor)', ArgDesc num-args 3, num-type-args 0, names []
|
||||
[1] = DirectCall 'dart:core::_List::filled (constructor)', ArgDesc num-args 2, num-type-args 1, names []
|
||||
[2] = Reserved
|
||||
}
|
||||
|
||||
@@ -427,7 +425,7 @@ Bytecode {
|
||||
}
|
||||
ConstantPool {
|
||||
[0] = TypeArgumentsField DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::E
|
||||
[1] = DirectCall 'dart:core::Map:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[1] = DirectCall 'dart:core::Map:: (constructor)', ArgDesc num-args 0, num-type-args 2, names []
|
||||
[2] = Reserved
|
||||
}
|
||||
|
||||
@@ -469,7 +467,7 @@ Bytecode {
|
||||
}
|
||||
ConstantPool {
|
||||
[0] = TypeArgumentsField DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::F
|
||||
[1] = DirectCall 'dart:core::Map:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[1] = DirectCall 'dart:core::Map:: (constructor)', ArgDesc num-args 0, num-type-args 2, names []
|
||||
[2] = Reserved
|
||||
}
|
||||
|
||||
@@ -503,15 +501,16 @@ Function 'testFactory', factory, static, reflectable, debuggable
|
||||
return-type DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::G < DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::G::testFactory (constructor)::TypeParam/0, DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::G::testFactory (constructor)::TypeParam/1 >
|
||||
|
||||
Bytecode {
|
||||
Entry 1
|
||||
Entry 2
|
||||
CheckFunctionTypeArgs 2, r0
|
||||
CheckStack 0
|
||||
Push FP[-5]
|
||||
PushNull
|
||||
Push r0
|
||||
InstantiateTypeArgumentsTOS 0, CP#1
|
||||
PushConstant CP#0
|
||||
AllocateT
|
||||
StoreLocal r0
|
||||
Push r0
|
||||
StoreLocal r1
|
||||
Push r1
|
||||
DirectCall CP#2, 1
|
||||
Drop1
|
||||
ReturnTOS
|
||||
@@ -574,15 +573,15 @@ Function 'testFactory2', factory, static, has-optional-named-params, reflectable
|
||||
return-type DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::I
|
||||
|
||||
Bytecode {
|
||||
EntryOptional 1, 0, 1
|
||||
LoadConstant r1, CP#0
|
||||
LoadConstant r1, CP#1
|
||||
EntryOptional 0, 0, 1
|
||||
LoadConstant r0, CP#0
|
||||
LoadConstant r0, CP#1
|
||||
Frame 1
|
||||
CheckStack 0
|
||||
Allocate CP#2
|
||||
StoreLocal r2
|
||||
Push r2
|
||||
StoreLocal r1
|
||||
Push r1
|
||||
Push r0
|
||||
DirectCall CP#3, 2
|
||||
Drop1
|
||||
ReturnTOS
|
||||
@@ -649,13 +648,14 @@ Function '', factory, static, reflectable, debuggable
|
||||
return-type DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::L < DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::L:: (constructor)::TypeParam/0, DART_SDK/pkg/dart2bytecode/testcases/instance_creation.dart::L:: (constructor)::TypeParam/1 >
|
||||
|
||||
Bytecode {
|
||||
Entry 1
|
||||
Entry 2
|
||||
CheckFunctionTypeArgs 2, r0
|
||||
CheckStack 0
|
||||
Push FP[-5]
|
||||
Push r0
|
||||
PushConstant CP#0
|
||||
AllocateT
|
||||
StoreLocal r0
|
||||
Push r0
|
||||
StoreLocal r1
|
||||
Push r1
|
||||
DirectCall CP#1, 1
|
||||
Drop1
|
||||
ReturnTOS
|
||||
|
||||
@@ -155,7 +155,7 @@ Bytecode {
|
||||
}
|
||||
ConstantPool {
|
||||
[0] = ObjectRef < dart:core::int >
|
||||
[1] = DirectCall 'dart:core::_GrowableList::_literal3 (constructor)', ArgDesc num-args 4, num-type-args 0, names []
|
||||
[1] = DirectCall 'dart:core::_GrowableList::_literal3 (constructor)', ArgDesc num-args 3, num-type-args 1, names []
|
||||
[2] = Reserved
|
||||
[3] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[4] = Reserved
|
||||
@@ -256,7 +256,7 @@ Bytecode {
|
||||
ConstantPool {
|
||||
[0] = ObjectRef < dart:core::int, dart:core::int >
|
||||
[1] = ObjectRef < dynamic >
|
||||
[2] = DirectCall 'dart:core::Map::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
|
||||
[2] = DirectCall 'dart:core::Map::_fromLiteral (constructor)', ArgDesc num-args 1, num-type-args 2, names []
|
||||
[3] = Reserved
|
||||
[4] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[5] = Reserved
|
||||
|
||||
@@ -364,7 +364,7 @@ ConstantPool {
|
||||
[2] = Type dart:core::Map < DART_SDK/pkg/dart2bytecode/testcases/type_ops.dart::D::TypeParam/0, DART_SDK/pkg/dart2bytecode/testcases/type_ops.dart::D::TypeParam/1 >
|
||||
[3] = ObjectRef ''
|
||||
[4] = SubtypeTestCache
|
||||
[5] = DirectCall 'dart:core::_GrowableList::_literal1 (constructor)', ArgDesc num-args 2, num-type-args 0, names []
|
||||
[5] = DirectCall 'dart:core::_GrowableList::_literal1 (constructor)', ArgDesc num-args 1, num-type-args 1, names []
|
||||
[6] = Reserved
|
||||
[7] = InterfaceCall 'dart:core::List::[]', ArgDesc num-args 2, num-type-args 0, names []
|
||||
[8] = Reserved
|
||||
@@ -403,23 +403,28 @@ Function '', factory, static, reflectable, debuggable
|
||||
return-type DART_SDK/pkg/dart2bytecode/testcases/type_ops.dart::E < DART_SDK/pkg/dart2bytecode/testcases/type_ops.dart::E:: (constructor)::TypeParam/0 >
|
||||
|
||||
Bytecode {
|
||||
Entry 1
|
||||
CheckStack 0
|
||||
Push FP[-5]
|
||||
Entry 2
|
||||
CheckFunctionTypeArgs 1, r0
|
||||
JumpIfNotZeroTypeArgs L1
|
||||
PushConstant CP#0
|
||||
AllocateT
|
||||
StoreLocal r0
|
||||
PopLocal r0
|
||||
L1:
|
||||
CheckStack 0
|
||||
Push r0
|
||||
DirectCall CP#1, 1
|
||||
PushConstant CP#1
|
||||
AllocateT
|
||||
StoreLocal r1
|
||||
Push r1
|
||||
DirectCall CP#2, 1
|
||||
Drop1
|
||||
ReturnTOS
|
||||
}
|
||||
Default function type arguments: CP#3
|
||||
Default function type arguments: CP#0
|
||||
ConstantPool {
|
||||
[0] = Class DART_SDK/pkg/dart2bytecode/testcases/type_ops.dart::E
|
||||
[1] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/type_ops.dart::E::_ (constructor)', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[2] = Reserved
|
||||
[3] = ObjectRef < dart:core::String >
|
||||
[0] = ObjectRef < dart:core::String >
|
||||
[1] = Class DART_SDK/pkg/dart2bytecode/testcases/type_ops.dart::E
|
||||
[2] = DirectCall 'DART_SDK/pkg/dart2bytecode/testcases/type_ops.dart::E::_ (constructor)', ArgDesc num-args 1, num-type-args 0, names []
|
||||
[3] = Reserved
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user