mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 12:48:10 +00:00
[vm/kernel/bytecode] Add invocation kind to StaticICData constant
VM will use the invocation kind to distinguish between getters, setters and calls via field/getter. Change-Id: I97cf36bc8778533e53f8251c25b373fddec3c2e8 Reviewed-on: https://dart-review.googlesource.com/55581 Reviewed-by: Régis Crelier <regis@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
929b79e865
commit
68b19b4ff4
|
@ -63,8 +63,15 @@ type ConstantICData extends ConstantPoolEntry {
|
|||
ConstantIndex argDesc;
|
||||
}
|
||||
|
||||
enum InvocationKind {
|
||||
method, // x.foo(...) or foo(...)
|
||||
getter, // x.foo
|
||||
setter // x.foo = ...
|
||||
}
|
||||
|
||||
type ConstantStaticICData extends ConstantPoolEntry {
|
||||
Byte tag = 8;
|
||||
Byte invocationKind; // Index in InvocationKind enum.
|
||||
CanonicalNameReference target;
|
||||
ConstantIndex argDesc;
|
||||
}
|
||||
|
@ -468,13 +475,20 @@ class ConstantICData extends ConstantPoolEntry {
|
|||
bool operator ==(other) => identical(this, other);
|
||||
}
|
||||
|
||||
enum InvocationKind { method, getter, setter }
|
||||
|
||||
class ConstantStaticICData extends ConstantPoolEntry {
|
||||
final InvocationKind invocationKind;
|
||||
final Reference _reference;
|
||||
final int argDescConstantIndex;
|
||||
|
||||
ConstantStaticICData(Member member, int argDescConstantIndex)
|
||||
: this.byReference(member.reference, argDescConstantIndex);
|
||||
ConstantStaticICData.byReference(this._reference, this.argDescConstantIndex);
|
||||
ConstantStaticICData(
|
||||
InvocationKind invocationKind, Member member, int argDescConstantIndex)
|
||||
: this.byReference(
|
||||
invocationKind, member.reference, argDescConstantIndex);
|
||||
|
||||
ConstantStaticICData.byReference(
|
||||
this.invocationKind, this._reference, this.argDescConstantIndex);
|
||||
|
||||
Member get target => _reference.asMember;
|
||||
|
||||
|
@ -483,17 +497,23 @@ class ConstantStaticICData extends ConstantPoolEntry {
|
|||
|
||||
@override
|
||||
void writeValueToBinary(BinarySink sink) {
|
||||
sink.writeByte(invocationKind.index);
|
||||
sink.writeCanonicalNameReference(getCanonicalNameOfMember(target));
|
||||
sink.writeUInt30(argDescConstantIndex);
|
||||
}
|
||||
|
||||
ConstantStaticICData.readFromBinary(BinarySource source)
|
||||
: _reference = source.readCanonicalNameReference().getReference(),
|
||||
: invocationKind = InvocationKind.values[source.readByte()],
|
||||
_reference = source.readCanonicalNameReference().getReference(),
|
||||
argDescConstantIndex = source.readUInt();
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'StaticICData target \'$target\', arg-desc CP#$argDescConstantIndex';
|
||||
'StaticICData ' +
|
||||
(invocationKind == InvocationKind.getter
|
||||
? 'get '
|
||||
: (invocationKind == InvocationKind.setter ? 'set ' : '')) +
|
||||
'target \'$target\', arg-desc CP#$argDescConstantIndex';
|
||||
|
||||
// ConstantStaticICData entries are created per call site and should not be
|
||||
// merged, so ConstantStaticICData class uses identity [hashCode] and
|
||||
|
|
|
@ -235,10 +235,15 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
|
|||
asm.emitReturnTOS();
|
||||
}
|
||||
|
||||
void _genStaticCall(
|
||||
Member target, ConstantArgDesc argDesc, int totalArgCount) {
|
||||
void _genStaticCall(Member target, ConstantArgDesc argDesc, int totalArgCount,
|
||||
{bool isGet: false, bool isSet: false}) {
|
||||
assert(!isGet || !isSet);
|
||||
final argDescIndex = cp.add(argDesc);
|
||||
final icdataIndex = cp.add(new ConstantStaticICData(target, argDescIndex));
|
||||
final kind = isGet
|
||||
? InvocationKind.getter
|
||||
: (isSet ? InvocationKind.setter : InvocationKind.method);
|
||||
final icdataIndex =
|
||||
cp.add(new ConstantStaticICData(kind, target, argDescIndex));
|
||||
|
||||
asm.emitPushConstant(icdataIndex);
|
||||
asm.emitIndirectStaticCall(totalArgCount, argDescIndex);
|
||||
|
@ -848,7 +853,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
|
|||
node.receiver.accept(this);
|
||||
final target = node.target;
|
||||
if (target is Field || (target is Procedure && target.isGetter)) {
|
||||
_genStaticCall(target, new ConstantArgDesc(1), 1);
|
||||
_genStaticCall(target, new ConstantArgDesc(1), 1, isGet: true);
|
||||
} else {
|
||||
throw new UnsupportedOperationError(
|
||||
'Unsupported DirectPropertyGet with ${target.runtimeType} $target');
|
||||
|
@ -1053,7 +1058,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
|
|||
'Unsupported SuperPropertyGet without target');
|
||||
}
|
||||
if (target is Field || (target is Procedure && target.isGetter)) {
|
||||
_genStaticCall(target, new ConstantArgDesc(1), 1);
|
||||
_genStaticCall(target, new ConstantArgDesc(1), 1, isGet: true);
|
||||
} else {
|
||||
throw new UnsupportedOperationError(
|
||||
'Unsupported SuperPropertyGet with target ${target.runtimeType} $target');
|
||||
|
@ -1113,11 +1118,11 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
|
|||
fieldIndex); // TODO(alexmarkov): do we really need this?
|
||||
asm.emitPushStatic(fieldIndex);
|
||||
} else {
|
||||
_genStaticCall(target, new ConstantArgDesc(0), 0);
|
||||
_genStaticCall(target, new ConstantArgDesc(0), 0, isGet: true);
|
||||
}
|
||||
} else if (target is Procedure) {
|
||||
if (target.isGetter) {
|
||||
_genStaticCall(target, new ConstantArgDesc(0), 0);
|
||||
_genStaticCall(target, new ConstantArgDesc(0), 0, isGet: true);
|
||||
} else {
|
||||
final tearOffIndex = cp.add(new ConstantTearOff(target));
|
||||
asm.emitPushConstant(tearOffIndex);
|
||||
|
@ -1152,7 +1157,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
|
|||
int cpIndex = cp.add(new ConstantField(target));
|
||||
asm.emitStoreStaticTOS(cpIndex);
|
||||
} else {
|
||||
_genStaticCall(target, new ConstantArgDesc(1), 1);
|
||||
_genStaticCall(target, new ConstantArgDesc(1), 1, isSet: true);
|
||||
asm.emitDrop1();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ Bytecode {
|
|||
}
|
||||
ConstantPool {
|
||||
[0] = ArgDesc num-args 0, num-type-args 0, names []
|
||||
[1] = StaticICData target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
|
||||
[1] = StaticICData get target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
|
||||
[2] = ArgDesc num-args 1, num-type-args 0, names []
|
||||
[3] = StaticICData target '#lib::_NamespaceImpl::_getPointer', arg-desc CP#2
|
||||
[4] = Null
|
||||
|
@ -259,7 +259,7 @@ Bytecode {
|
|||
}
|
||||
ConstantPool {
|
||||
[0] = ArgDesc num-args 0, num-type-args 0, names []
|
||||
[1] = StaticICData target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
|
||||
[1] = StaticICData get target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
|
||||
[2] = Null
|
||||
}
|
||||
] static get _namespace() → self::_Namespace
|
||||
|
@ -276,7 +276,7 @@ Bytecode {
|
|||
}
|
||||
ConstantPool {
|
||||
[0] = ArgDesc num-args 0, num-type-args 0, names []
|
||||
[1] = StaticICData target '#lib::_NamespaceImpl::_namespacePointer', arg-desc CP#0
|
||||
[1] = StaticICData get target '#lib::_NamespaceImpl::_namespacePointer', arg-desc CP#0
|
||||
[2] = Null
|
||||
}
|
||||
] static get _namespacePointer() → core::int
|
||||
|
@ -714,7 +714,7 @@ ConstantPool {
|
|||
[9] = ArgDesc num-args 1, num-type-args 0, names []
|
||||
[10] = StaticICData target 'dart.core::Uri::parse', arg-desc CP#9
|
||||
[11] = ArgDesc num-args 0, num-type-args 0, names []
|
||||
[12] = StaticICData target 'dart.core::Uri::base', arg-desc CP#11
|
||||
[12] = StaticICData get target 'dart.core::Uri::base', arg-desc CP#11
|
||||
[13] = Null
|
||||
[14] = StaticICData target 'dart.core::_Uri::file', arg-desc CP#9
|
||||
[15] = ICData target-name 'resolveUri', arg-desc CP#2
|
||||
|
@ -744,7 +744,7 @@ Bytecode {
|
|||
ConstantPool {
|
||||
[0] = TearOff #lib::_scriptUri
|
||||
[1] = ArgDesc num-args 1, num-type-args 0, names []
|
||||
[2] = StaticICData target '#lib::VMLibraryHooks::platformScript', arg-desc CP#1
|
||||
[2] = StaticICData set target '#lib::VMLibraryHooks::platformScript', arg-desc CP#1
|
||||
[3] = Null
|
||||
}
|
||||
]static method _setupHooks() → dynamic {
|
||||
|
|
|
@ -125,7 +125,7 @@ Bytecode {
|
|||
}
|
||||
ConstantPool {
|
||||
[0] = ArgDesc num-args 1, num-type-args 0, names []
|
||||
[1] = StaticICData target '#lib::A::_name', arg-desc CP#0
|
||||
[1] = StaticICData get target '#lib::A::_name', arg-desc CP#0
|
||||
[2] = Null
|
||||
}
|
||||
] method toString() → core::String
|
||||
|
|
Loading…
Reference in a new issue