struct objectref * class_resolver_lookup_string(struct vm * vm, struct class_entry * class_entry, const int string_index) { debugf("class_resolver_lookup_string: %d\n", string_index); if (class_entry->attribute_entry[string_index - 1].string_objectref != nullptr) { debugf("class_resolver_lookup_string: [cached]\n"); return class_entry->attribute_entry[string_index - 1].string_objectref; } struct constant * string_constant = &class_entry->class_file->constant_pool[string_index - 1]; assert(string_constant->tag == CONSTANT_String); struct constant * utf8_constant = &class_entry->class_file->constant_pool[string_constant->string.string_index - 1]; assert(utf8_constant->tag == CONSTANT_Utf8); struct class_entry * string_class_entry = class_resolver_lookup_class(vm->class_hash_table.length, vm->class_hash_table.entry, (const uint8_t *)"java/lang/String", 16); debugf("string class entry: %p\n", string_class_entry); int32_t count = utf8_constant->utf8.length; struct arrayref * arrayref = prim_array_allocate(vm, 1, count); assert(arrayref != nullptr); arrayref->class_entry = nullptr; // byte[] arrayref->length = utf8_constant->utf8.length; for (int i = 0; i < utf8_constant->utf8.length; i++) { arrayref->u8[i] = utf8_constant->utf8.bytes[i]; } assert(string_class_entry != nullptr); int fields_count = string_class_entry->instance_fields_count; struct objectref * objectref = obj_allocate(vm, fields_count); assert(objectref != nullptr); objectref->class_entry = string_class_entry; for (int i = 0; i < fields_count; i++) { objectref->oref[i] = nullptr; } objectref->aref[0] = arrayref; // cache the result class_entry->attribute_entry[string_index - 1].string_objectref = objectref; return objectref; } static inline void class_entry_field_entry_from_constant_index(struct vm * vm, int32_t index, struct class_entry ** class_entry, struct field_entry ** field_entry, struct constant ** field_descriptor_constant) { struct constant * fieldref_constant = &vm->current_frame->class_entry->class_file->constant_pool[index - 1]; #ifdef DEBUG assert(fieldref_constant->tag == CONSTANT_Fieldref); #endif *class_entry = class_resolver_lookup_class_from_class_index(vm->class_hash_table.length, vm->class_hash_table.entry, vm->current_frame->class_entry, fieldref_constant->fieldref.class_index); assert(*class_entry != nullptr); int fields_hash_table_length = (*class_entry)->fields.length; struct hash_table_entry * fields_hash_table = (*class_entry)->fields.entry; *field_entry = class_resolver_lookup_field_from_fieldref_index(fields_hash_table_length, fields_hash_table, vm->current_frame->class_entry, index); assert(*field_entry != nullptr); struct constant * nameandtype_constant = &vm->current_frame->class_entry->class_file->constant_pool[fieldref_constant->fieldref.name_and_type_index - 1]; #ifdef DEBUG assert(nameandtype_constant->tag == CONSTANT_NameAndType); #endif *field_descriptor_constant = &vm->current_frame->class_entry->class_file->constant_pool[nameandtype_constant->nameandtype.descriptor_index - 1]; #ifdef DEBUG assert((*field_descriptor_constant)->tag == CONSTANT_Utf8); #endif }