Replace is_synthetic bit on Fields with is_reflectable. Mark private fields of dart:* as non-reflectable.

This fixes an inconsistency in mirrors where some classes in dart:* would claim to have a field but throw NSM if one attempts to access it, and prevents accessing private static fields of dart:* that don't have implicit getters or setters.

R=asiva@google.com

Review URL: https://codereview.chromium.org//1280713002 .
This commit is contained in:
Ryan Macnak 2015-08-06 16:48:01 -07:00
parent 0f13b9c931
commit b34267d0d7
5 changed files with 28 additions and 25 deletions

View file

@ -1077,7 +1077,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_members, 3) {
Field& field = Field::Handle();
for (intptr_t i = 0; i < num_fields; i++) {
field ^= fields.At(i);
if (!field.is_synthetic()) {
if (field.is_reflectable()) {
member_mirror = CreateVariableMirror(field, owner_mirror);
member_mirrors.Add(member_mirror);
}
@ -1172,7 +1172,7 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) {
}
} else if (entry.IsField()) {
const Field& field = Field::Cast(entry);
if (!field.is_synthetic()) {
if (field.is_reflectable()) {
member_mirror = CreateVariableMirror(field, owner_mirror);
member_mirrors.Add(member_mirror);
}
@ -1609,7 +1609,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
return result.raw();
}
if (field.is_final()) {
if (field.is_final() || !field.is_reflectable()) {
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
internal_setter_name,
setter,
@ -1906,7 +1906,7 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) {
return result.raw();
}
if (field.is_final()) {
if (field.is_final() || !field.is_reflectable()) {
ThrowNoSuchMethod(Instance::null_instance(),
internal_setter_name,
setter,

View file

@ -1473,7 +1473,7 @@ RawError* Object::Init(Isolate* isolate) {
#define ADD_SET_FIELD(clazz) \
field_name = Symbols::New("cid"#clazz); \
field = Field::New(field_name, true, false, true, true, cls, 0); \
field = Field::New(field_name, true, false, true, false, cls, 0); \
value = Smi::New(k##clazz##Cid); \
field.set_value(value); \
field.set_type(Type::Handle(Type::IntType())); \
@ -7214,7 +7214,7 @@ RawField* Field::New(const String& name,
bool is_static,
bool is_final,
bool is_const,
bool is_synthetic,
bool is_reflectable,
const Class& owner,
intptr_t token_pos) {
ASSERT(!owner.IsNull());
@ -7228,7 +7228,7 @@ RawField* Field::New(const String& name,
}
result.set_is_final(is_final);
result.set_is_const(is_const);
result.set_is_synthetic(is_synthetic);
result.set_is_reflectable(is_reflectable);
result.set_owner(owner);
result.set_token_pos(token_pos);
result.set_has_initializer(false);
@ -7443,7 +7443,7 @@ RawInstance* Field::AccessorClosure(bool make_setter) const {
true, // is_static
true, // is_final
true, // is_const
true, // is_synthetic
false, // is_reflectable
field_owner,
this->token_pos());
closure_field.set_value(Instance::Cast(result));
@ -9032,7 +9032,7 @@ void Library::AddMetadata(const Class& cls,
true, // is_static
false, // is_final
false, // is_const
true, // is_synthetic
false, // is_reflectable
cls,
token_pos));
field.set_type(Type::Handle(Type::DynamicType()));
@ -10540,7 +10540,7 @@ void Namespace::AddMetadata(intptr_t token_pos, const Class& owner_class) {
true, // is_static
false, // is_final
false, // is_const
true, // is_synthetic
false, // is_reflectable
owner_class,
token_pos));
field.set_type(Type::Handle(Type::DynamicType()));

View file

@ -2814,8 +2814,8 @@ class Field : public Object {
bool is_static() const { return StaticBit::decode(raw_ptr()->kind_bits_); }
bool is_final() const { return FinalBit::decode(raw_ptr()->kind_bits_); }
bool is_const() const { return ConstBit::decode(raw_ptr()->kind_bits_); }
bool is_synthetic() const {
return SyntheticBit::decode(raw_ptr()->kind_bits_);
bool is_reflectable() const {
return ReflectableBit::decode(raw_ptr()->kind_bits_);
}
inline intptr_t Offset() const;
@ -2838,7 +2838,7 @@ class Field : public Object {
bool is_static,
bool is_final,
bool is_const,
bool is_synthetic,
bool is_reflectable,
const Class& owner,
intptr_t token_pos);
@ -2987,7 +2987,7 @@ class Field : public Object {
kFinalBit,
kHasInitializerBit,
kUnboxingCandidateBit,
kSyntheticBit
kReflectableBit
};
class ConstBit : public BitField<bool, kConstBit, 1> {};
class StaticBit : public BitField<bool, kStaticBit, 1> {};
@ -2996,7 +2996,7 @@ class Field : public Object {
class UnboxingCandidateBit : public BitField<bool,
kUnboxingCandidateBit, 1> {
};
class SyntheticBit : public BitField<bool, kSyntheticBit, 1> {};
class ReflectableBit : public BitField<bool, kReflectableBit, 1> {};
// Update guarded cid and guarded length for this field. Returns true, if
// deoptimization of dependent code is required.
@ -3012,8 +3012,8 @@ class Field : public Object {
void set_is_const(bool value) const {
set_kind_bits(ConstBit::update(value, raw_ptr()->kind_bits_));
}
void set_is_synthetic(bool value) const {
set_kind_bits(SyntheticBit::update(value, raw_ptr()->kind_bits_));
void set_is_reflectable(bool value) const {
set_kind_bits(ReflectableBit::update(value, raw_ptr()->kind_bits_));
}
void set_owner(const Object& value) const {
StorePointer(&raw_ptr()->owner_, value.raw());

View file

@ -281,7 +281,7 @@ TEST_CASE(InstanceClass) {
const Array& one_fields = Array::Handle(Array::New(1));
const String& field_name = String::Handle(Symbols::New("the_field"));
const Field& field = Field::Handle(
Field::New(field_name, false, false, false, false, one_field_class, 0));
Field::New(field_name, false, false, false, true, one_field_class, 0));
one_fields.SetAt(0, field);
one_field_class.SetFields(one_fields);
one_field_class.Finalize();
@ -2991,7 +2991,7 @@ static RawField* CreateTestField(const char* name) {
const Class& cls = Class::Handle(CreateTestClass("global:"));
const String& field_name = String::Handle(Symbols::New(name));
const Field& field =
Field::Handle(Field::New(field_name, true, false, false, false, cls, 0));
Field::Handle(Field::New(field_name, true, false, false, true, cls, 0));
return field.raw();
}

View file

@ -3988,11 +3988,13 @@ void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) {
}
// Create the field object.
const bool is_reflectable =
!(library_.is_dart_scheme() && library_.IsPrivate(*field->name));
class_field = Field::New(*field->name,
field->has_static,
field->has_final,
field->has_const,
false, // Not synthetic.
is_reflectable,
current_class(),
field->name_pos);
class_field.set_type(*field->type);
@ -4671,7 +4673,7 @@ void Parser::ParseEnumDefinition(const Class& cls) {
false, // Not static.
true, // Field is final.
false, // Not const.
false, // Not synthetic.
true, // Is reflectable.
cls,
cls.token_pos());
index_field.set_type(int_type);
@ -4743,7 +4745,7 @@ void Parser::ParseEnumDefinition(const Class& cls) {
/* is_static = */ true,
/* is_final = */ true,
/* is_const = */ true,
/* is_synthetic = */ false,
/* is_reflectable = */ true,
cls,
cls.token_pos());
enum_value.set_type(dynamic_type);
@ -4781,7 +4783,7 @@ void Parser::ParseEnumDefinition(const Class& cls) {
/* is_static = */ true,
/* is_final = */ true,
/* is_const = */ true,
/* is_synthetic = */ false,
/* is_reflectable = */ true,
cls,
cls.token_pos());
values_field.set_type(Type::Handle(Z, Type::ArrayType()));
@ -5365,7 +5367,6 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level,
// Const fields are implicitly final.
const bool is_final = is_const || (CurrentToken() == Token::kFINAL);
const bool is_static = true;
const bool is_synthetic = false;
const AbstractType& type = AbstractType::ZoneHandle(Z,
ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters));
Field& field = Field::Handle(Z);
@ -5393,7 +5394,9 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level,
var_name.ToCString());
}
field = Field::New(var_name, is_static, is_final, is_const, is_synthetic,
const bool is_reflectable =
!(library_.is_dart_scheme() && library_.IsPrivate(var_name));
field = Field::New(var_name, is_static, is_final, is_const, is_reflectable,
current_class(), name_pos);
field.set_type(type);
field.set_value(Instance::Handle(Z, Instance::null()));