914 "tried to access field %s.%s from class %s", 915 sel_klass->external_name(), 916 fd.name()->as_C_string(), 917 ref_klass->external_name() 918 ); 919 return; 920 } 921 } 922 923 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) { 924 LinkInfo link_info(pool, index, method, CHECK); 925 resolve_field(fd, link_info, byte, true, CHECK); 926 } 927 928 void LinkResolver::resolve_field(fieldDescriptor& fd, 929 const LinkInfo& link_info, 930 Bytecodes::Code byte, bool initialize_class, 931 TRAPS) { 932 assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic || 933 byte == Bytecodes::_getfield || byte == Bytecodes::_putfield || 934 byte == Bytecodes::_vwithfield || 935 byte == Bytecodes::_nofast_getfield || byte == Bytecodes::_nofast_putfield || 936 (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode"); 937 938 bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic); 939 bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield 940 || byte == Bytecodes::_vwithfield); 941 // Check if there's a resolved klass containing the field 942 Klass* resolved_klass = link_info.resolved_klass(); 943 Symbol* field = link_info.name(); 944 Symbol* sig = link_info.signature(); 945 946 if (resolved_klass == NULL) { 947 ResourceMark rm(THREAD); 948 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); 949 } 950 951 // Resolve instance field 952 Klass* sel_klass = resolved_klass->find_field(field, sig, &fd); 953 // check if field exists; i.e., if a klass containing the field def has been selected 954 if (sel_klass == NULL) { 955 ResourceMark rm(THREAD); 956 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); 957 } 958 959 if (!link_info.check_access()) 960 // Access checking may be turned off when calling from within the VM. 964 Klass* current_klass = link_info.current_klass(); 965 check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK); 966 967 // check for errors 968 if (is_static != fd.is_static()) { 969 ResourceMark rm(THREAD); 970 char msg[200]; 971 jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string()); 972 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg); 973 } 974 975 // A final field can be modified only 976 // (1) by methods declared in the class declaring the field and 977 // (2) by the <clinit> method (in case of a static field) 978 // or by the <init> method (in case of an instance field). 979 if (is_put && fd.access_flags().is_final()) { 980 ResourceMark rm(THREAD); 981 stringStream ss; 982 983 if (sel_klass != current_klass) { 984 // For Minimal Value Types check if the current class is an anonymous 985 // class whose host class is the Derived Value Type class (selected class) 986 // or the Value Capable Class (VCC) 987 if (byte == Bytecodes::_vwithfield) { 988 assert(sel_klass->is_value(), "Expected Value Type"); 989 if (current_klass->is_instance_klass() && InstanceKlass::cast(current_klass)->is_anonymous()) { 990 Klass* host_klass = InstanceKlass::cast(current_klass)->host_klass(); // Is host VCC of DVT ? 991 992 if (sel_klass == host_klass || // Is DVT 993 (host_klass->is_instance_klass() && // Is VCC 994 InstanceKlass::cast(sel_klass)->get_vcc_klass() == host_klass)) { 995 return; 996 } 997 } 998 } 999 1000 ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class", 1001 is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), 1002 current_klass->external_name()); 1003 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); 1004 } 1005 1006 if (fd.constants()->pool_holder()->major_version() >= 53) { 1007 methodHandle m = link_info.current_method(); 1008 assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes"); 1009 bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic && 1010 fd.is_static() && 1011 !m()->is_static_initializer()); 1012 bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && 1013 !fd.is_static() && 1014 !m->is_object_initializer()); 1015 1016 if (is_initialized_static_final_update || is_initialized_instance_final_update) { 1017 ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ", 1018 is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), 1019 m()->name()->as_C_string(), | 914 "tried to access field %s.%s from class %s", 915 sel_klass->external_name(), 916 fd.name()->as_C_string(), 917 ref_klass->external_name() 918 ); 919 return; 920 } 921 } 922 923 void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, const methodHandle& method, Bytecodes::Code byte, TRAPS) { 924 LinkInfo link_info(pool, index, method, CHECK); 925 resolve_field(fd, link_info, byte, true, CHECK); 926 } 927 928 void LinkResolver::resolve_field(fieldDescriptor& fd, 929 const LinkInfo& link_info, 930 Bytecodes::Code byte, bool initialize_class, 931 TRAPS) { 932 assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic || 933 byte == Bytecodes::_getfield || byte == Bytecodes::_putfield || 934 byte == Bytecodes::_withfield || 935 byte == Bytecodes::_nofast_getfield || byte == Bytecodes::_nofast_putfield || 936 (byte == Bytecodes::_nop && !link_info.check_access()), "bad field access bytecode"); 937 938 bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic); 939 bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic || byte == Bytecodes::_nofast_putfield 940 || byte == Bytecodes::_withfield); 941 // Check if there's a resolved klass containing the field 942 Klass* resolved_klass = link_info.resolved_klass(); 943 Symbol* field = link_info.name(); 944 Symbol* sig = link_info.signature(); 945 946 if (resolved_klass == NULL) { 947 ResourceMark rm(THREAD); 948 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); 949 } 950 951 // Resolve instance field 952 Klass* sel_klass = resolved_klass->find_field(field, sig, &fd); 953 // check if field exists; i.e., if a klass containing the field def has been selected 954 if (sel_klass == NULL) { 955 ResourceMark rm(THREAD); 956 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); 957 } 958 959 if (!link_info.check_access()) 960 // Access checking may be turned off when calling from within the VM. 964 Klass* current_klass = link_info.current_klass(); 965 check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK); 966 967 // check for errors 968 if (is_static != fd.is_static()) { 969 ResourceMark rm(THREAD); 970 char msg[200]; 971 jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string()); 972 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg); 973 } 974 975 // A final field can be modified only 976 // (1) by methods declared in the class declaring the field and 977 // (2) by the <clinit> method (in case of a static field) 978 // or by the <init> method (in case of an instance field). 979 if (is_put && fd.access_flags().is_final()) { 980 ResourceMark rm(THREAD); 981 stringStream ss; 982 983 if (sel_klass != current_klass) { 984 ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class", 985 is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), 986 current_klass->external_name()); 987 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); 988 } 989 990 if (fd.constants()->pool_holder()->major_version() >= 53) { 991 methodHandle m = link_info.current_method(); 992 assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes"); 993 bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic && 994 fd.is_static() && 995 !m()->is_static_initializer()); 996 bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && 997 !fd.is_static() && 998 !m->is_object_initializer()); 999 1000 if (is_initialized_static_final_update || is_initialized_instance_final_update) { 1001 ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ", 1002 is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), 1003 m()->name()->as_C_string(), |