Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 12b7af8

Browse files
authored
Merge pull request #13 from hankluo6/field
Support parent fields in getfield and putfield
2 parents 7331be2 + 15a4a3e commit 12b7af8

File tree

7 files changed

+89
-25
lines changed

7 files changed

+89
-25
lines changed

‎.clang-format‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ UseTab: Never
1313
IndentWidth: 4
1414
BreakBeforeBraces: Linux
1515
AccessModifierOffset: -4
16+
ForEachMacros:
17+
- list_for_each

‎classfile.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ typedef struct {
5454
variable_t *static_var; /* store static fields in the class */
5555
} field_t;
5656

57-
typedef struct {
57+
typedef struct class_file{
5858
constant_pool_t constant_pool;
5959
class_info_t *info;
6060
method_t *methods;
6161
field_t *fields;
6262
u2 fields_count;
6363
bool initialized;
64+
struct class_file *next;
65+
struct class_file *prev;
6466
} class_file_t;
6567

6668
typedef struct {

‎jvm.c‎

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "class-heap.h"
1313
#include "classfile.h"
1414
#include "constant-pool.h"
15+
#include "list.h"
1516
#include "object-heap.h"
1617
#include "stack.h"
1718

@@ -1114,7 +1115,11 @@ stack_entry_t *execute(method_t *method,
11141115
find_field_info_from_index(index, clazz, &field_name,
11151116
&field_descriptor);
11161117

1117-
variable_t *addr = find_field_addr(obj, field_name);
1118+
variable_t *addr = NULL;
1119+
while (!addr) {
1120+
addr = find_field_addr(obj, field_name);
1121+
obj = obj->parent;
1122+
}
11181123

11191124
switch (field_descriptor[0]) {
11201125
case 'I':
@@ -1166,7 +1171,11 @@ stack_entry_t *execute(method_t *method,
11661171
find_field_info_from_index(index, clazz, &field_name,
11671172
&field_descriptor);
11681173

1169-
variable_t *var = find_field_addr(obj, field_name);
1174+
variable_t *var = NULL;
1175+
while (!var) {
1176+
var = find_field_addr(obj, field_name);
1177+
obj = obj->parent;
1178+
}
11701179

11711180
switch (field_descriptor[0]) {
11721181
case 'I':
@@ -1197,22 +1206,20 @@ stack_entry_t *execute(method_t *method,
11971206
char *class_name = find_class_name_from_index(index, clazz);
11981207
class_file_t *target_class;
11991208

1200-
/* FIXME: use linked list to prevent wasted space */
1201-
class_file_t**stack=malloc(sizeof(class_file_t*) *100);
1202-
size_tcount=0;
1203-
while (true) {
1209+
class_file_t*list =calloc(1, sizeof(class_file_t));
1210+
init_list(list);
1211+
1212+
while (strcmp(class_name, "java/lang/Object")) {
12041213
find_or_add_class_to_heap(class_name, prefix, &target_class);
12051214
assert(target_class && "Failed to load class in i_new");
1206-
stack[count++] =target_class;
1215+
list_add(target_class, list);
12071216
class_name = find_class_name_from_index(
12081217
target_class->info->super_class, target_class);
1209-
if (!strcmp(class_name, "java/lang/Object"))
1210-
break;
12111218
}
12121219

1213-
/* call static initialization */
1214-
while (count) {
1215-
target_class=stack[--count];
1220+
/* reversely call static initialization if class have not been
1221+
* initialized */
1222+
list_for_each (target_class, list) {
12161223
if (target_class->initialized)
12171224
continue;
12181225
target_class->initialized = true;
@@ -1226,10 +1233,11 @@ stack_entry_t *execute(method_t *method,
12261233
free(exec_res);
12271234
}
12281235
}
1229-
free(stack);
12301236

1231-
object_t *object = create_object(target_class);
1237+
object_t *object = create_object(list);
12321238
push_ref(op_stack, object);
1239+
list_del(list);
1240+
free(list);
12331241

12341242
pc += 3;
12351243
break;

‎list.h‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
3+
#define init_list(list) list->prev = list->next = list;
4+
5+
#define list_is_head(list, head) (list == head)
6+
7+
#define list_add(new, head) \
8+
head->next->prev = new; \
9+
new->next = head->next; \
10+
new->prev = head; \
11+
head->next = new;
12+
13+
#define list_del(entry) \
14+
entry->prev->next = entry->next; \
15+
entry->next->prev = entry->prev;
16+
17+
#define list_for_each(pos, head) \
18+
for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next)

‎object-heap.c‎

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,29 @@ void init_object_heap()
1212
object_heap.length = 0;
1313
}
1414

15+
/**
16+
* Create an java object.
17+
*
18+
* @param clazz the list of classes that contains the created class and all its
19+
* parent classess
20+
* @return the object that wanted to be created
21+
*/
1522
object_t *create_object(class_file_t *clazz)
1623
{
17-
object_t *new_obj = malloc(sizeof(object_t));
18-
new_obj->fields_count = clazz->fields_count;
19-
new_obj->value = calloc(sizeof(variable_t), new_obj->fields_count);
20-
for (int i = 0; i < clazz->fields_count; ++i) {
21-
new_obj->value[i].type = VAR_NONE;
24+
object_t *new_obj = NULL, *parent = NULL;
25+
class_file_t *pos;
26+
list_for_each (pos, clazz) {
27+
new_obj = malloc(sizeof(object_t));
28+
new_obj->fields_count = pos->fields_count;
29+
new_obj->value = calloc(sizeof(variable_t), new_obj->fields_count);
30+
new_obj->parent = parent;
31+
for (int i = 0; i < pos->fields_count; ++i) {
32+
new_obj->value[i].type = VAR_NONE;
33+
}
34+
new_obj->class = pos;
35+
parent = new_obj;
2236
}
23-
new_obj->class=clazz;
37+
/* only store object that really is needed in object heap */
2438
object_heap.objects[object_heap.length++] = new_obj;
2539

2640
return new_obj;
@@ -34,15 +48,18 @@ variable_t *find_field_addr(object_t *obj, char *name)
3448
return &obj->value[i];
3549
}
3650
}
37-
assert(0 && "Can't find field in the object");
3851
return NULL;
3952
}
4053

4154
void free_object_heap()
4255
{
4356
for (int i = 0; i < object_heap.length; ++i) {
44-
free(object_heap.objects[i]->value);
45-
free(object_heap.objects[i]);
57+
/* free object and all its parent */
58+
for (object_t *cur = object_heap.objects[i], *next; cur; cur = next) {
59+
next = cur->parent;
60+
free(cur->value);
61+
free(cur);
62+
}
4663
}
4764
free(object_heap.objects);
4865
}

‎object-heap.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#pragma once
22

33
#include "classfile.h"
4+
#include "list.h"
45

5-
typedef struct {
6+
typedef struct object{
67
variable_t *value;
78
class_file_t *class;
89
size_t fields_count;
10+
struct object *parent;
911
} object_t;
1012

1113
typedef struct {

‎tests/Inherit.java‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
public class Inherit {
22
static int x = 1;
3+
int y = 5;
34

45
public static void static_call() {
56
System.out.println(1);
@@ -27,6 +28,20 @@ public static void main(String[] args) {
2728
System.out.println(objA.x);
2829
System.out.println(objB.x);
2930

31+
/* check fields */
32+
System.out.println(obj.y);
33+
System.out.println(objA.y);
34+
System.out.println(objB.y);
35+
obj.y = 2;
36+
System.out.println(obj.y);
37+
System.out.println(objA.y);
38+
System.out.println(objB.y);
39+
objA.y = 3;
40+
objB.y = 5;
41+
System.out.println(obj.y);
42+
System.out.println(objA.y);
43+
System.out.println(objB.y);
44+
3045
/* check static methods inheritance (compiler will replace objects with classes) */
3146
obj.static_call();
3247
objA.static_call();

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /