mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:59:47 +00:00
Add partial instantiation support for constant evaluator [PartialInstantiationConstant]
Change-Id: Iaa93da60331737aaa6bceb4d2fe1d791dc7e95e9 Reviewed-on: https://dart-review.googlesource.com/52445 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
2d6dfb1ea9
commit
e9ffc02663
|
@ -902,11 +902,22 @@ type InstanceConstant extends Constant {
|
|||
List<[FieldReference, ConstantReference]> values;
|
||||
}
|
||||
|
||||
type TearOffConstant extends Constant {
|
||||
type PartialInstantiationConstant extends Constant {
|
||||
Byte tag = 8;
|
||||
ConstantReference tearOffConstant;
|
||||
List<DartType> typeArguments;
|
||||
}
|
||||
|
||||
type TearOffConstant extends Constant {
|
||||
Byte tag = 9;
|
||||
CanonicalNameReference staticProcedureReference;
|
||||
}
|
||||
|
||||
type TypeLiteralConstant extends Constant {
|
||||
Byte tag = 10;
|
||||
DartType type;
|
||||
}
|
||||
|
||||
abstract type Statement extends Node {}
|
||||
|
||||
type ExpressionStatement extends Statement {
|
||||
|
|
|
@ -5386,6 +5386,34 @@ class InstanceConstant extends Constant {
|
|||
}
|
||||
}
|
||||
|
||||
class PartialInstantiationConstant extends Constant {
|
||||
final TearOffConstant tearOffConstant;
|
||||
final List<DartType> types;
|
||||
|
||||
PartialInstantiationConstant(this.tearOffConstant, this.types);
|
||||
|
||||
visitChildren(Visitor v) {
|
||||
tearOffConstant.acceptReference(v);
|
||||
visitList(types, v);
|
||||
}
|
||||
|
||||
accept(ConstantVisitor v) => v.visitPartialInstantiationConstant(this);
|
||||
acceptReference(Visitor v) =>
|
||||
v.visitPartialInstantiationConstantReference(this);
|
||||
|
||||
String toString() {
|
||||
return '${runtimeType}(${tearOffConstant.procedure}<${types.join(', ')}>)';
|
||||
}
|
||||
|
||||
int get hashCode => tearOffConstant.hashCode ^ listHashCode(types);
|
||||
|
||||
bool operator ==(Object other) {
|
||||
return other is PartialInstantiationConstant &&
|
||||
other.tearOffConstant == tearOffConstant &&
|
||||
listEquals(other.types, types);
|
||||
}
|
||||
}
|
||||
|
||||
class TearOffConstant extends Constant {
|
||||
final Reference procedureReference;
|
||||
|
||||
|
|
|
@ -215,6 +215,14 @@ class BinaryBuilder {
|
|||
fieldValues[fieldRef] = constant;
|
||||
}
|
||||
return new InstanceConstant(classReference, typeArguments, fieldValues);
|
||||
case ConstantTag.PartialInstantiationConstant:
|
||||
final tearOffConstant = readConstantReference() as TearOffConstant;
|
||||
final int length = readUInt();
|
||||
final List<DartType> types = new List<DartType>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
types[i] = readDartType();
|
||||
}
|
||||
return new PartialInstantiationConstant(tearOffConstant, types);
|
||||
case ConstantTag.TearOffConstant:
|
||||
final Reference reference = readCanonicalNameReference().getReference();
|
||||
return new TearOffConstant.byReference(reference);
|
||||
|
|
|
@ -175,6 +175,14 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
|||
writeCanonicalNameReference(fieldRef.canonicalName);
|
||||
writeConstantReference(value);
|
||||
});
|
||||
} else if (constant is PartialInstantiationConstant) {
|
||||
writeByte(ConstantTag.PartialInstantiationConstant);
|
||||
writeConstantReference(constant.tearOffConstant);
|
||||
final int length = constant.types.length;
|
||||
writeUInt30(length);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
writeDartType(constant.types[i]);
|
||||
}
|
||||
} else if (constant is TearOffConstant) {
|
||||
writeByte(ConstantTag.TearOffConstant);
|
||||
writeCanonicalNameReference(constant.procedure.canonicalName);
|
||||
|
@ -1896,6 +1904,19 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
|||
throw new UnsupportedError('serialization of StringConstant references');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPartialInstantiationConstant(PartialInstantiationConstant node) {
|
||||
throw new UnsupportedError(
|
||||
'serialization of PartialInstantiationConstants ');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitPartialInstantiationConstantReference(
|
||||
PartialInstantiationConstant node) {
|
||||
throw new UnsupportedError(
|
||||
'serialization of PartialInstantiationConstant references');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTearOffConstant(TearOffConstant node) {
|
||||
throw new UnsupportedError('serialization of TearOffConstants ');
|
||||
|
|
|
@ -147,6 +147,7 @@ abstract class ConstantTag {
|
|||
static const int MapConstant = 5;
|
||||
static const int ListConstant = 6;
|
||||
static const int InstanceConstant = 7;
|
||||
static const int TearOffConstant = 8;
|
||||
static const int TypeLiteralConstant = 9;
|
||||
static const int PartialInstantiationConstant = 8;
|
||||
static const int TearOffConstant = 9;
|
||||
static const int TypeLiteralConstant = 10;
|
||||
}
|
||||
|
|
|
@ -729,6 +729,22 @@ class ConstantEvaluator extends RecursiveVisitor {
|
|||
return canonicalize(backend.buildSymbolConstant(value));
|
||||
}
|
||||
|
||||
visitInstantiation(Instantiation node) {
|
||||
final Constant constant = evaluate(node.expression);
|
||||
if (constant is TearOffConstant) {
|
||||
if (node.typeArguments.length ==
|
||||
constant.procedure.function.typeParameters.length) {
|
||||
return canonicalize(
|
||||
new PartialInstantiationConstant(constant, node.typeArguments));
|
||||
}
|
||||
throw new ConstantEvaluationError(
|
||||
'The number of type arguments supplied in the partial instantiation '
|
||||
'does not match the number of type arguments of the $constant.');
|
||||
}
|
||||
throw new ConstantEvaluationError(
|
||||
'Only tear-off constants can be partially instantiated.');
|
||||
}
|
||||
|
||||
// Helper methods:
|
||||
|
||||
void ensureIsSubtype(Constant constant, DartType type) {
|
||||
|
|
|
@ -283,6 +283,8 @@ class ConstantVisitor<R> {
|
|||
R visitMapConstant(MapConstant node) => defaultConstant(node);
|
||||
R visitListConstant(ListConstant node) => defaultConstant(node);
|
||||
R visitInstanceConstant(InstanceConstant node) => defaultConstant(node);
|
||||
R visitPartialInstantiationConstant(PartialInstantiationConstant node) =>
|
||||
defaultConstant(node);
|
||||
R visitTearOffConstant(TearOffConstant node) => defaultConstant(node);
|
||||
R visitTypeLiteralConstant(TypeLiteralConstant node) => defaultConstant(node);
|
||||
}
|
||||
|
@ -334,6 +336,8 @@ class Visitor<R> extends TreeVisitor<R>
|
|||
R visitMapConstant(MapConstant node) => defaultConstant(node);
|
||||
R visitListConstant(ListConstant node) => defaultConstant(node);
|
||||
R visitInstanceConstant(InstanceConstant node) => defaultConstant(node);
|
||||
R visitPartialInstantiationConstant(PartialInstantiationConstant node) =>
|
||||
defaultConstant(node);
|
||||
R visitTearOffConstant(TearOffConstant node) => defaultConstant(node);
|
||||
R visitTypeLiteralConstant(TypeLiteralConstant node) => defaultConstant(node);
|
||||
|
||||
|
@ -359,6 +363,9 @@ class Visitor<R> extends TreeVisitor<R>
|
|||
defaultConstantReference(node);
|
||||
R visitInstanceConstantReference(InstanceConstant node) =>
|
||||
defaultConstantReference(node);
|
||||
R visitPartialInstantiationConstantReference(
|
||||
PartialInstantiationConstant node) =>
|
||||
defaultConstantReference(node);
|
||||
R visitTearOffConstantReference(TearOffConstant node) =>
|
||||
defaultConstantReference(node);
|
||||
R visitTypeLiteralConstantReference(TypeLiteralConstant node) =>
|
||||
|
|
|
@ -10884,6 +10884,35 @@ const Array& ConstantHelper::ReadConstantTable() {
|
|||
temp_instance_ = H.Canonicalize(temp_instance_);
|
||||
break;
|
||||
}
|
||||
case kPartialInstantiationConstant: {
|
||||
const intptr_t entry_index = builder_.ReadUInt();
|
||||
temp_object_ = constants.At(entry_index);
|
||||
|
||||
const intptr_t number_of_type_arguments = builder_.ReadUInt();
|
||||
if (temp_class_.NumTypeArguments() > 0) {
|
||||
temp_type_arguments_ =
|
||||
TypeArguments::New(number_of_type_arguments, Heap::kOld);
|
||||
for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
|
||||
temp_type_arguments_.SetTypeAt(j, type_translator_.BuildType());
|
||||
}
|
||||
} else {
|
||||
ASSERT(number_of_type_arguments == 0);
|
||||
temp_type_arguments_ = TypeArguments::null();
|
||||
}
|
||||
|
||||
// Make a copy of the old closure, with the delayed type arguments
|
||||
// set to [temp_type_arguments_].
|
||||
temp_closure_ = Closure::RawCast(temp_object_.raw());
|
||||
temp_function_ = temp_closure_.function();
|
||||
temp_type_arguments2_ = temp_closure_.instantiator_type_arguments();
|
||||
temp_type_arguments3_ = temp_closure_.function_type_arguments();
|
||||
temp_context_ = temp_closure_.context();
|
||||
temp_closure_ = Closure::New(
|
||||
temp_type_arguments2_, Object::null_type_arguments(),
|
||||
temp_type_arguments_, temp_function_, temp_context_, Heap::kOld);
|
||||
temp_instance_ = H.Canonicalize(temp_closure_);
|
||||
break;
|
||||
}
|
||||
case kTearOffConstant: {
|
||||
const NameIndex index = builder_.ReadCanonicalNameReference();
|
||||
NameIndex lib_index = index;
|
||||
|
|
|
@ -1680,12 +1680,16 @@ class ConstantHelper {
|
|||
zone_(zone),
|
||||
temp_type_(AbstractType::Handle(zone)),
|
||||
temp_type_arguments_(TypeArguments::Handle(zone)),
|
||||
temp_type_arguments2_(TypeArguments::Handle(zone)),
|
||||
temp_type_arguments3_(TypeArguments::Handle(zone)),
|
||||
temp_object_(Object::Handle(zone)),
|
||||
temp_array_(Array::Handle(zone)),
|
||||
temp_instance_(Instance::Handle(zone)),
|
||||
temp_field_(Field::Handle(zone)),
|
||||
temp_class_(Class::Handle(zone)),
|
||||
temp_function_(Function::Handle(zone)),
|
||||
temp_closure_(Closure::Handle(zone)),
|
||||
temp_context_(Context::Handle(zone)),
|
||||
temp_integer_(Integer::Handle(zone)) {}
|
||||
|
||||
// Reads the constant table from the binary.
|
||||
|
@ -1707,12 +1711,16 @@ class ConstantHelper {
|
|||
Zone* zone_;
|
||||
AbstractType& temp_type_;
|
||||
TypeArguments& temp_type_arguments_;
|
||||
TypeArguments& temp_type_arguments2_;
|
||||
TypeArguments& temp_type_arguments3_;
|
||||
Object& temp_object_;
|
||||
Array& temp_array_;
|
||||
Instance& temp_instance_;
|
||||
Field& temp_field_;
|
||||
Class& temp_class_;
|
||||
Function& temp_function_;
|
||||
Closure& temp_closure_;
|
||||
Context& temp_context_;
|
||||
Integer& temp_integer_;
|
||||
};
|
||||
|
||||
|
|
|
@ -149,8 +149,9 @@ enum ConstantTag {
|
|||
kMapConstant = 5,
|
||||
kListConstant = 6,
|
||||
kInstanceConstant = 7,
|
||||
kTearOffConstant = 8,
|
||||
kTypeLiteralConstant = 9,
|
||||
kPartialInstantiationConstant = 8,
|
||||
kTearOffConstant = 9,
|
||||
kTypeLiteralConstant = 10,
|
||||
};
|
||||
|
||||
static const int SpecializedIntLiteralBias = 3;
|
||||
|
|
|
@ -22765,6 +22765,16 @@ RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
|
|||
const Function& function,
|
||||
const Context& context,
|
||||
Heap::Space space) {
|
||||
return Closure::New(instantiator_type_arguments, function_type_arguments,
|
||||
Object::empty_type_arguments(), function, context, space);
|
||||
}
|
||||
|
||||
RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
|
||||
const TypeArguments& function_type_arguments,
|
||||
const TypeArguments& delayed_type_arguments,
|
||||
const Function& function,
|
||||
const Context& context,
|
||||
Heap::Space space) {
|
||||
Closure& result = Closure::Handle();
|
||||
{
|
||||
RawObject* raw =
|
||||
|
@ -22776,7 +22786,7 @@ RawClosure* Closure::New(const TypeArguments& instantiator_type_arguments,
|
|||
result.StorePointer(&result.raw_ptr()->function_type_arguments_,
|
||||
function_type_arguments.raw());
|
||||
result.StorePointer(&result.raw_ptr()->delayed_type_arguments_,
|
||||
Object::empty_type_arguments().raw());
|
||||
delayed_type_arguments.raw());
|
||||
result.StorePointer(&result.raw_ptr()->function_, function.raw());
|
||||
result.StorePointer(&result.raw_ptr()->context_, context.raw());
|
||||
}
|
||||
|
|
|
@ -8791,6 +8791,13 @@ class Closure : public Instance {
|
|||
const Context& context,
|
||||
Heap::Space space = Heap::kNew);
|
||||
|
||||
static RawClosure* New(const TypeArguments& instantiator_type_arguments,
|
||||
const TypeArguments& function_type_arguments,
|
||||
const TypeArguments& delayed_type_arguments,
|
||||
const Function& function,
|
||||
const Context& context,
|
||||
Heap::Space space = Heap::kNew);
|
||||
|
||||
RawFunction* GetInstantiatedSignature(Zone* zone) const;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in a new issue