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:
Martin Kustermann 2018-04-25 09:25:28 +00:00 committed by commit-bot@chromium.org
parent 2d6dfb1ea9
commit e9ffc02663
12 changed files with 153 additions and 6 deletions

View file

@ -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 {

View file

@ -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;

View file

@ -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);

View file

@ -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 ');

View file

@ -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;
}

View file

@ -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) {

View file

@ -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) =>

View file

@ -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;

View file

@ -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_;
};

View file

@ -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;

View file

@ -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());
}

View file

@ -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: