class_resolver: correct behavior for instance field lookup from superclass
This commit is contained in:
parent
e22f2e87e8
commit
2fe03bf38f
@ -56,41 +56,50 @@ static int32_t count_superclass_instance_fields(int class_hash_table_length,
|
|||||||
return instance_field_count;
|
return instance_field_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_superclass_instance_fields(int class_hash_table_length,
|
static int add_superclass_instance_fields(int class_hash_table_length,
|
||||||
struct hash_table_entry * class_hash_table,
|
struct hash_table_entry * class_hash_table,
|
||||||
int fields_hash_table_length,
|
int fields_hash_table_length,
|
||||||
struct hash_table_entry * fields_hash_table,
|
struct hash_table_entry * fields_hash_table,
|
||||||
struct class_entry * class_entry,
|
struct class_entry * class_entry,
|
||||||
struct field_entry * field_entry,
|
int instance_index)
|
||||||
int instance_index)
|
|
||||||
{
|
{
|
||||||
while (class_entry->class_file->super_class != 0) {
|
if (class_entry->class_file->super_class != 0) {
|
||||||
class_entry = class_resolver_lookup_class_from_class_index(class_hash_table_length,
|
struct class_entry * superclass_entry = class_resolver_lookup_class_from_class_index(class_hash_table_length,
|
||||||
class_hash_table,
|
class_hash_table,
|
||||||
class_entry,
|
class_entry,
|
||||||
class_entry->class_file->super_class);
|
class_entry->class_file->super_class);
|
||||||
assert(class_entry != nullptr);
|
assert(superclass_entry != nullptr);
|
||||||
|
instance_index = add_superclass_instance_fields(class_hash_table_length,
|
||||||
|
class_hash_table,
|
||||||
|
fields_hash_table_length,
|
||||||
|
fields_hash_table,
|
||||||
|
superclass_entry,
|
||||||
|
instance_index);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < class_entry->class_file->fields_count; i++) {
|
for (int i = 0; i < class_entry->class_file->fields_count; i++) {
|
||||||
struct field_info * field_info = &class_entry->class_file->fields[i];
|
struct field_info * field_info = &class_entry->class_file->fields[i];
|
||||||
if (!(field_info->access_flags & FIELD_ACC_STATIC)) {
|
if (!(field_info->access_flags & FIELD_ACC_STATIC)) {
|
||||||
field_entry[i].instance_index = instance_index;
|
struct field_entry * field_entry = malloc_class_arena((sizeof (struct field_entry)));
|
||||||
field_entry[i].field_info = field_info;
|
field_entry->instance_index = instance_index;
|
||||||
instance_index += field_info_field_size(class_entry->class_file, field_info);
|
field_entry->field_info = field_info;
|
||||||
|
|
||||||
struct constant * name_constant = &class_entry->class_file->constant_pool[field_info->name_index - 1];
|
struct constant * name_constant = &class_entry->class_file->constant_pool[field_info->name_index - 1];
|
||||||
assert(name_constant->tag == CONSTANT_Utf8);
|
assert(name_constant->tag == CONSTANT_Utf8);
|
||||||
debugf("hash table entry for field: ");
|
debugf("hash table entry for instance field: ");
|
||||||
print_utf8_string(name_constant);
|
print_utf8_string(name_constant);
|
||||||
debugf(": %d\n", instance_index);
|
debugf(": %d %p\n", instance_index, field_entry);
|
||||||
hash_table_add(fields_hash_table_length,
|
hash_table_add(fields_hash_table_length,
|
||||||
fields_hash_table,
|
fields_hash_table,
|
||||||
name_constant->utf8.bytes,
|
name_constant->utf8.bytes,
|
||||||
name_constant->utf8.length,
|
name_constant->utf8.length,
|
||||||
(void *)&field_entry[i]);
|
(void *)field_entry);
|
||||||
}
|
|
||||||
|
instance_index += field_info_field_size(class_entry->class_file, field_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return instance_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t class_resolver_create_fields_hash_table(int class_hash_table_length,
|
static int32_t class_resolver_create_fields_hash_table(int class_hash_table_length,
|
||||||
@ -104,47 +113,43 @@ static int32_t class_resolver_create_fields_hash_table(int class_hash_table_leng
|
|||||||
uint32_t fields_hash_table_size = (sizeof (struct hash_table_entry)) * fields_hash_table_length;
|
uint32_t fields_hash_table_size = (sizeof (struct hash_table_entry)) * fields_hash_table_length;
|
||||||
struct hash_table_entry * fields_hash_table = malloc_class_arena(fields_hash_table_size);
|
struct hash_table_entry * fields_hash_table = malloc_class_arena(fields_hash_table_size);
|
||||||
|
|
||||||
uint32_t field_entry_size = (sizeof (struct field_entry)) * total_fields_count;
|
int static_index = 0;
|
||||||
struct field_entry * field_entry = malloc_class_arena(field_entry_size);
|
|
||||||
|
|
||||||
int32_t static_index = 0;
|
|
||||||
int32_t instance_index = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < class_entry->class_file->fields_count; i++) {
|
for (int i = 0; i < class_entry->class_file->fields_count; i++) {
|
||||||
struct field_info * field_info = &class_entry->class_file->fields[i];
|
struct field_info * field_info = &class_entry->class_file->fields[i];
|
||||||
if (field_info->access_flags & FIELD_ACC_STATIC) {
|
if (field_info->access_flags & FIELD_ACC_STATIC) {
|
||||||
field_entry[i].static_index = static_index;
|
struct field_entry * field_entry = malloc_class_arena((sizeof (struct field_entry)));
|
||||||
|
field_entry->static_index = static_index;
|
||||||
|
field_entry->field_info = field_info;
|
||||||
static_index += field_info_field_size(class_entry->class_file, field_info);
|
static_index += field_info_field_size(class_entry->class_file, field_info);
|
||||||
} else {
|
|
||||||
field_entry[i].instance_index = instance_index;
|
|
||||||
instance_index += field_info_field_size(class_entry->class_file, field_info);
|
|
||||||
}
|
|
||||||
field_entry[i].field_info = field_info;
|
|
||||||
|
|
||||||
struct constant * name_constant = &class_entry->class_file->constant_pool[field_info->name_index - 1];
|
struct constant * name_constant = &class_entry->class_file->constant_pool[field_info->name_index - 1];
|
||||||
assert(name_constant->tag == CONSTANT_Utf8);
|
assert(name_constant->tag == CONSTANT_Utf8);
|
||||||
debugf("hash table entry for field: ");
|
debugf("hash table entry for static field: ");
|
||||||
print_utf8_string(name_constant);
|
print_utf8_string(name_constant);
|
||||||
debugf(": %d\n", i);
|
debugf(": %d %p\n", static_index, field_entry);
|
||||||
hash_table_add(fields_hash_table_length,
|
|
||||||
fields_hash_table,
|
hash_table_add(fields_hash_table_length,
|
||||||
name_constant->utf8.bytes,
|
fields_hash_table,
|
||||||
name_constant->utf8.length,
|
name_constant->utf8.bytes,
|
||||||
(void *)&field_entry[i]);
|
name_constant->utf8.length,
|
||||||
|
(void *)field_entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int instance_index = add_superclass_instance_fields(class_hash_table_length,
|
||||||
|
class_hash_table,
|
||||||
|
fields_hash_table_length,
|
||||||
|
fields_hash_table,
|
||||||
|
class_entry,
|
||||||
|
0);
|
||||||
|
|
||||||
|
debugf("static_index=%d instance_index=%d total_fields_count=%d\n", static_index, instance_index, total_fields_count);
|
||||||
|
|
||||||
class_entry->fields.length = fields_hash_table_length;
|
class_entry->fields.length = fields_hash_table_length;
|
||||||
class_entry->fields.entry = fields_hash_table;
|
class_entry->fields.entry = fields_hash_table;
|
||||||
class_entry->instance_fields_count = instance_index;
|
class_entry->instance_fields_count = instance_index;
|
||||||
|
|
||||||
add_superclass_instance_fields(class_hash_table_length,
|
|
||||||
class_hash_table,
|
|
||||||
fields_hash_table_length,
|
|
||||||
fields_hash_table,
|
|
||||||
class_entry,
|
|
||||||
&field_entry[class_entry->class_file->fields_count],
|
|
||||||
instance_index);
|
|
||||||
|
|
||||||
return static_index;
|
return static_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,6 +330,7 @@ struct field_entry * class_resolver_lookup_field(int fields_hash_table_length,
|
|||||||
field_name,
|
field_name,
|
||||||
field_name_length);
|
field_name_length);
|
||||||
assert(e != nullptr);
|
assert(e != nullptr);
|
||||||
|
debugf("%p\n", e->value);
|
||||||
|
|
||||||
return (struct field_entry *)e->value;
|
return (struct field_entry *)e->value;
|
||||||
}
|
}
|
||||||
|
36
p/InstanceFields.java
Normal file
36
p/InstanceFields.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package p;
|
||||||
|
|
||||||
|
class Super {
|
||||||
|
public int aa;
|
||||||
|
public int bb;
|
||||||
|
|
||||||
|
int bar() {
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Fields extends Super {
|
||||||
|
public int cc;
|
||||||
|
public int dd;
|
||||||
|
|
||||||
|
int foo() {
|
||||||
|
return bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InstanceFields {
|
||||||
|
public static int test() {
|
||||||
|
Fields f = new Fields();
|
||||||
|
f.aa = 11;
|
||||||
|
f.bb = 22;
|
||||||
|
f.cc = 33;
|
||||||
|
f.dd = 44;
|
||||||
|
|
||||||
|
return f.foo();
|
||||||
|
//return f.bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main() {
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user