47 ShouldNotReachHere();
48 return bogus_type();
49 }
50 }
51
52 bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Symbol* name,
53 Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) {
54 HandleMark hm(THREAD);
55 Klass* this_class;
56 if (klass->is_hidden() && klass->name() == name) {
57 this_class = klass;
58 } else {
59 this_class = SystemDictionary::resolve_or_fail(
60 name, Handle(THREAD, klass->class_loader()),
61 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
62 if (log_is_enabled(Debug, class, resolve)) {
63 Verifier::trace_class_resolution(this_class, klass);
64 }
65 }
66
67 if (this_class->is_interface() && (!from_field_is_protected ||
68 from_name != vmSymbols::java_lang_Object())) {
69 // If we are not trying to access a protected field or method in
70 // java.lang.Object then, for arrays, we only allow assignability
71 // to interfaces java.lang.Cloneable and java.io.Serializable.
72 // Otherwise, we treat interfaces as java.lang.Object.
73 return !from_is_array ||
74 this_class == vmClasses::Cloneable_klass() ||
75 this_class == vmClasses::Serializable_klass();
76 } else if (from_is_object) {
77 Klass* from_class;
78 if (klass->is_hidden() && klass->name() == from_name) {
79 from_class = klass;
80 } else {
81 from_class = SystemDictionary::resolve_or_fail(
82 from_name, Handle(THREAD, klass->class_loader()),
83 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
84 if (log_is_enabled(Debug, class, resolve)) {
85 Verifier::trace_class_resolution(from_class, klass);
86 }
87 }
88 return from_class->is_subclass_of(this_class);
89 }
90
91 return false;
107 if (name() == vmSymbols::java_lang_Object()) {
108 // any object or array is assignable to java.lang.Object
109 return true;
110 }
111
112 if (Arguments::is_dumping_archive()) {
113 if (SystemDictionaryShared::add_verification_constraint(klass,
114 name(), from.name(), from_field_is_protected, from.is_array(),
115 from.is_object())) {
116 // If add_verification_constraint() returns true, the resolution/check should be
117 // delayed until runtime.
118 return true;
119 }
120 }
121
122 return resolve_and_check_assignability(klass, name(), from.name(),
123 from_field_is_protected, from.is_array(), from.is_object(), THREAD);
124 } else if (is_array() && from.is_array()) {
125 VerificationType comp_this = get_component(context);
126 VerificationType comp_from = from.get_component(context);
127 if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
128 return comp_this.is_component_assignable_from(comp_from, context,
129 from_field_is_protected, THREAD);
130 }
131 }
132 return false;
133 }
134
135 VerificationType VerificationType::get_component(ClassVerifier *context) const {
136 assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
137 SignatureStream ss(name(), false);
138 ss.skip_array_prefix(1);
139 switch (ss.type()) {
140 case T_BOOLEAN: return VerificationType(Boolean);
141 case T_BYTE: return VerificationType(Byte);
142 case T_CHAR: return VerificationType(Char);
143 case T_SHORT: return VerificationType(Short);
144 case T_INT: return VerificationType(Integer);
145 case T_LONG: return VerificationType(Long);
146 case T_FLOAT: return VerificationType(Float);
147 case T_DOUBLE: return VerificationType(Double);
148 case T_ARRAY:
149 case T_OBJECT: {
150 guarantee(ss.is_reference(), "unchecked verifier input?");
151 Symbol* component = ss.as_symbol();
152 // Create another symbol to save as signature stream unreferences this symbol.
153 Symbol* component_copy = context->create_temporary_symbol(component);
154 assert(component_copy == component, "symbols don't match");
155 return VerificationType::reference_type(component_copy);
156 }
157 default:
158 // Met an invalid type signature, e.g. [X
159 return VerificationType::bogus_type();
160 }
161 }
162
163 void VerificationType::print_on(outputStream* st) const {
164 switch (_u._data) {
165 case Bogus: st->print("top"); break;
166 case Category1: st->print("category1"); break;
167 case Category2: st->print("category2"); break;
168 case Category2_2nd: st->print("category2_2nd"); break;
169 case Boolean: st->print("boolean"); break;
170 case Byte: st->print("byte"); break;
171 case Short: st->print("short"); break;
172 case Char: st->print("char"); break;
173 case Integer: st->print("integer"); break;
174 case Float: st->print("float"); break;
175 case Long: st->print("long"); break;
176 case Double: st->print("double"); break;
177 case Long_2nd: st->print("long_2nd"); break;
178 case Double_2nd: st->print("double_2nd"); break;
179 case Null: st->print("null"); break;
180 case ReferenceQuery: st->print("reference type"); break;
181 case Category1Query: st->print("category1 type"); break;
182 case Category2Query: st->print("category2 type"); break;
183 case Category2_2ndQuery: st->print("category2_2nd type"); break;
184 default:
185 if (is_uninitialized_this()) {
186 st->print("uninitializedThis");
187 } else if (is_uninitialized()) {
188 st->print("uninitialized %d", bci());
189 } else {
190 if (name() != NULL) {
191 name()->print_value_on(st);
192 } else {
193 st->print_cr("NULL");
194 }
195 }
196 }
197 }
|
47 ShouldNotReachHere();
48 return bogus_type();
49 }
50 }
51
52 bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Symbol* name,
53 Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) {
54 HandleMark hm(THREAD);
55 Klass* this_class;
56 if (klass->is_hidden() && klass->name() == name) {
57 this_class = klass;
58 } else {
59 this_class = SystemDictionary::resolve_or_fail(
60 name, Handle(THREAD, klass->class_loader()),
61 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
62 if (log_is_enabled(Debug, class, resolve)) {
63 Verifier::trace_class_resolution(this_class, klass);
64 }
65 }
66
67 if (this_class->access_flags().is_value_class()) return false;
68 if (this_class->is_interface() && (!from_field_is_protected ||
69 from_name != vmSymbols::java_lang_Object())) {
70 // If we are not trying to access a protected field or method in
71 // java.lang.Object then, for arrays, we only allow assignability
72 // to interfaces java.lang.Cloneable and java.io.Serializable
73 // Otherwise, we treat interfaces as java.lang.Object.
74 return !from_is_array ||
75 this_class == vmClasses::Cloneable_klass() ||
76 this_class == vmClasses::Serializable_klass();
77 } else if (from_is_object) {
78 Klass* from_class;
79 if (klass->is_hidden() && klass->name() == from_name) {
80 from_class = klass;
81 } else {
82 from_class = SystemDictionary::resolve_or_fail(
83 from_name, Handle(THREAD, klass->class_loader()),
84 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
85 if (log_is_enabled(Debug, class, resolve)) {
86 Verifier::trace_class_resolution(from_class, klass);
87 }
88 }
89 return from_class->is_subclass_of(this_class);
90 }
91
92 return false;
108 if (name() == vmSymbols::java_lang_Object()) {
109 // any object or array is assignable to java.lang.Object
110 return true;
111 }
112
113 if (Arguments::is_dumping_archive()) {
114 if (SystemDictionaryShared::add_verification_constraint(klass,
115 name(), from.name(), from_field_is_protected, from.is_array(),
116 from.is_object())) {
117 // If add_verification_constraint() returns true, the resolution/check should be
118 // delayed until runtime.
119 return true;
120 }
121 }
122
123 return resolve_and_check_assignability(klass, name(), from.name(),
124 from_field_is_protected, from.is_array(), from.is_object(), THREAD);
125 } else if (is_array() && from.is_array()) {
126 VerificationType comp_this = get_component(context);
127 VerificationType comp_from = from.get_component(context);
128
129 /*
130 // This code implements non-covariance between inline type arrays and both
131 // arrays of objects and arrays of interface types. If covariance is
132 // supported for inline type arrays then this code should be removed.
133 if (comp_from.is_inline_type() && !comp_this.is_null() && comp_this.is_reference()) {
134 // An array of inline types is not assignable to an array of java.lang.Objects.
135 if (comp_this.name() == vmSymbols::java_lang_Object()) {
136 return false;
137 }
138
139 // Need to load 'comp_this' to see if it is an interface.
140 InstanceKlass* klass = context->current_class();
141 {
142 HandleMark hm(THREAD);
143 Klass* comp_this_class = SystemDictionary::resolve_or_fail(
144 comp_this.name(), Handle(THREAD, klass->class_loader()),
145 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
146 klass->class_loader_data()->record_dependency(comp_this_class);
147 if (log_is_enabled(Debug, class, resolve)) {
148 Verifier::trace_class_resolution(comp_this_class, klass);
149 }
150 // An array of inline types is not assignable to an array of interface types.
151 if (comp_this_class->is_interface()) {
152 return false;
153 }
154 }
155 }
156 */
157 if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
158 return comp_this.is_component_assignable_from(comp_from, context,
159 from_field_is_protected, THREAD);
160 }
161 }
162 return false;
163 }
164
165 bool VerificationType::is_inline_type_assignable_from(const VerificationType& from) const {
166 // Check that 'from' is not null, is an inline type, and is the same inline type.
167 assert(is_inline_type(), "called with a non-inline type");
168 assert(!is_null(), "inline type is not null");
169 return (!from.is_null() && from.is_inline_type() && name() == from.name());
170 }
171
172 bool VerificationType::is_ref_assignable_from_inline_type(const VerificationType& from, ClassVerifier* context, TRAPS) const {
173 assert(!from.is_null(), "Inline type should not be null");
174 if (!is_null() && (name()->is_same_fundamental_type(from.name()) ||
175 name() == vmSymbols::java_lang_Object())) {
176 return true;
177 }
178
179 // Need to load 'this' to see if it is an interface or supertype.
180 InstanceKlass* klass = context->current_class();
181 {
182 HandleMark hm(THREAD);
183 Klass* this_class = SystemDictionary::resolve_or_fail(
184 name(), Handle(THREAD, klass->class_loader()),
185 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
186 klass->class_loader_data()->record_dependency(this_class);
187 if (log_is_enabled(Debug, class, resolve)) {
188 Verifier::trace_class_resolution(this_class, klass);
189 }
190 if (this_class->is_interface()) {
191 return true;
192 } else {
193 Klass* from_class = SystemDictionary::resolve_or_fail(
194 from.name(), Handle(THREAD, klass->class_loader()),
195 Handle(THREAD, klass->protection_domain()), true, CHECK_false);
196 if (log_is_enabled(Debug, class, resolve)) {
197 Verifier::trace_class_resolution(from_class, klass);
198 }
199 return from_class->is_subclass_of(this_class);
200 }
201 }
202 }
203
204 VerificationType VerificationType::get_component(ClassVerifier *context) const {
205 assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
206 SignatureStream ss(name(), false);
207 ss.skip_array_prefix(1);
208 switch (ss.type()) {
209 case T_BOOLEAN: return VerificationType(Boolean);
210 case T_BYTE: return VerificationType(Byte);
211 case T_CHAR: return VerificationType(Char);
212 case T_SHORT: return VerificationType(Short);
213 case T_INT: return VerificationType(Integer);
214 case T_LONG: return VerificationType(Long);
215 case T_FLOAT: return VerificationType(Float);
216 case T_DOUBLE: return VerificationType(Double);
217 case T_ARRAY:
218 case T_OBJECT:
219 case T_PRIMITIVE_OBJECT: {
220 guarantee(ss.is_reference(), "unchecked verifier input?");
221 Symbol* component = ss.as_symbol();
222 // Create another symbol to save as signature stream unreferences this symbol.
223 Symbol* component_copy = context->create_temporary_symbol(component);
224 assert(component_copy == component, "symbols don't match");
225 return (ss.type() == T_PRIMITIVE_OBJECT) ?
226 VerificationType::inline_type(component_copy) :
227 VerificationType::reference_type(component_copy);
228 }
229 default:
230 // Met an invalid type signature, e.g. [X
231 return VerificationType::bogus_type();
232 }
233 }
234
235 void VerificationType::print_on(outputStream* st) const {
236 switch (_u._data) {
237 case Bogus: st->print("top"); break;
238 case Category1: st->print("category1"); break;
239 case Category2: st->print("category2"); break;
240 case Category2_2nd: st->print("category2_2nd"); break;
241 case Boolean: st->print("boolean"); break;
242 case Byte: st->print("byte"); break;
243 case Short: st->print("short"); break;
244 case Char: st->print("char"); break;
245 case Integer: st->print("integer"); break;
246 case Float: st->print("float"); break;
247 case Long: st->print("long"); break;
248 case Double: st->print("double"); break;
249 case Long_2nd: st->print("long_2nd"); break;
250 case Double_2nd: st->print("double_2nd"); break;
251 case Null: st->print("null"); break;
252 case ReferenceQuery: st->print("reference type"); break;
253 case InlineTypeQuery: st->print("inline type"); break;
254 case NonScalarQuery: st->print("reference or inline type"); break;
255 case Category1Query: st->print("category1 type"); break;
256 case Category2Query: st->print("category2 type"); break;
257 case Category2_2ndQuery: st->print("category2_2nd type"); break;
258 default:
259 if (is_uninitialized_this()) {
260 st->print("uninitializedThis");
261 } else if (is_uninitialized()) {
262 st->print("uninitialized %d", bci());
263 } else if (is_inline_type()) {
264 name()->print_Qvalue_on(st);
265 } else {
266 if (name() != NULL) {
267 name()->print_value_on(st);
268 } else {
269 st->print_cr("NULL");
270 }
271 }
272 }
273 }
|