-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjvm.h
492 lines (406 loc) · 16.3 KB
/
jvm.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
/**
* @file jvm.h
* @brief Interpreter
* File containing the main implementation of the interpreter.
*
*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "classfile.h"
#include "frame.h"
#include "methodarea.h"
#include "opcodes.h"
#include "object.h"
#define MAX_FRAMES 32
#define MAXHEAP 256
#define MAXSTATICS 256
/**
* @brief Static attribute.
*
* Structure to store a static attribute of a class.
*/
typedef struct Static {
char *class; /**< Class name */
char *name; /**< Attribute name */
char *type; /**< Attribute type name */
ObjectField value; /**< Attribute value */
} Static;
/**
* @brief Interpreter structure.
*
* Structure that stores the information utilized by the JVM interpreter and defines it.
*/
typedef struct JVM {
uint32_t pc; /**< Program counter */
Frame *frames[MAX_FRAMES]; /**< Pointer to frame stack */
int32_t frame_index; /**< Top index of frame stack */
/* uint8_t *heap; */
MethodArea *method_area; /**< Pointer to method area */
/* NativeMethodArea nma; */
int32_t current_class_index;
int32_t current_method_index;
bool jmp; /**< If will ocurr a jump */
bool ret; /**< If will return */
uint64_t retval; /**< Value that will be returned */
void *heap[MAXHEAP]; /**< Pointer to heap area */
int32_t heap_index; /**< Top index of heap */
Static *statics[MAXSTATICS]; /**< Pointer to static objects stack*/
int32_t static_index; /**< Top index of static stack*/
} JVM;
/**
* Initializes JVM memory area pointed to by jvm pointer.
* @param jvm non-null pointer to jvm struct to be initialized
*/
void init_jvm(JVM *jvm);
/**
* Deinitializes JVM memory area pointed to by jvm pointer.
* Notably, heap, frames, and auxiliary structures are freed
* @param jvm non-null pointer to jvm struct to be deinitialized
*/
void deinit_jvm(JVM *jvm);
/**
* Load the classfile into the jvm's MethodArea
* Classfile reference is directly assigned (will not be copied in any way).
* Therefore the allocated memory must be persitent and is maintained by the user.
* @param jvm non-null pointer to jvm to which cf will be loaded
* @param cf classfile to be loaded
*/
void jvm_load_classfile(JVM *jvm, classfile *cf);
/**
* Load the class with class_name into the jvm's MethodArea
* File will be read from disk. An assertion will check whether the file can be read.
* @param jvm non-null pointer to jvm to which class will be loaded
* @param class_name name of the class to be loaded (without .class extension)
*/
void jvm_load_class(JVM *jvm, char *class_name);
/**
* Set class which owns current method being run
* Assumes class is already loaded
* @param jvm non-null pointer to jvm to which class will be set
* @param class_name name of the class to be set as current
*/
void jvm_set_current_class(JVM *jvm, char *class_name);
/**
* Set current method to run
* Assumes method belongs to class set as current.
* @param jvm non-null pointer to jvm to which method will be set
* @param method_name name of the method to be set as current
*/
void jvm_set_current_method(JVM *jvm, char *method_name);
void jvm_exec_clinit(JVM *jvm);
/**
* Set the current class and current method members with index in MethodArea.
* Assumes that the current class does contain the method required
* @param jvm non-null pointer to jvm to which method will be set
* @param class_index index to classfile in JVM's MethodArea
* @param method_index index to the desired method in the classfile
*/
void jvm_load_method(JVM *jvm, uint32_t class_index, uint32_t method_index);
/**
* Returns a reference to the class which runs the method being run
* @param jvm pointer to jvm
*/
classfile *jvm_get_current_class(JVM *jvm);
/**
* Returns the name of the class which runs the method being run
* @param jvm pointer to jvm
*/
char *jvm_get_current_class_name(JVM *jvm);
/**
* Returns a reference to the method being run
* @param jvm pointer to jvm
*/
method_info *jvm_get_current_method(JVM *jvm);
/**
* Returns the name of the method being run
* @param jvm pointer to jvm
*/
char *jvm_get_current_method_name(JVM *jvm);
/**
* Creates a frame for a call to the current method and pushes it onto the frame stack of jvm
* @param jvm pointer to jvm
*/
void jvm_push_frame(JVM *jvm);
/**
* Pop the current frame off the stack and free all its resources
* @param jvm pointer to jvm
*/
void jvm_pop_frame(JVM *jvm);
/**
* Returns a pointer to the frame on top of the stack
* @param jvm pointer to jvm
*/
Frame *jvm_peek_frame(JVM *jvm);
/** Run one jvm cycle
* Returns 0 when return from main or clinit is called, 1 otherwise
* @param jvm pointer to jvm
*/
int jvm_cycle(JVM *jvm);
/**
* Runs until return from main or clinit is reached.
* @param jvm pointer to jvm
*/
void jvm_run(JVM *jvm);
/**
* Load current method into frame stack and run it
* @param jvm pointer to jvm
*/
void jvm_run_method(JVM *jvm);
/**
* Returns whether jvm is currently running a main method
* @param jvm pointer to jvm
*/
int jvm_in_main(JVM *jvm);
/**
* Returns whether jvm is currently running <clinit> method
* @param jvm pointer to jvm
*/
bool jvm_in_clinit(JVM *jvm);
/**
* Save current frame context
* PC, current class and current method's indexes are saved to frame (typically the callee).
* @param jvm pointer to jvm
*/
void jvm_save_context(JVM *jvm);
/**
* Restore context to previous frame (callee)
* PC and previous class' and method's indexes are restored.
* @param jvm pointer to jvm
*/
void jvm_restore_context(JVM *jvm);
/**
* Add new pointer to jvm's heap table
* The heap space is for memory allocated during runtime.
* When an object is allocated, it persists until the JVM is deinitialized.
* Upon deinitialization, all heap memory is freed.
* The heap uses a stack structure, where the latest placed pointers are freed first.
* Therefore, nested structures must have their 'leafs' placed after the 'parents' (i.e. 2d,3d arrays)
* @param jvm pointer to jvm
* @param ptr pointer to be added to the heap
*/
void jvm_add_to_heap(JVM *jvm, void *ptr);
typedef void (*operation)(Frame *, uint32_t, uint32_t);
void nop(Frame *f, uint32_t a0, uint32_t a1);
void ldc(Frame *f, uint32_t a0, uint32_t a1);
void istore(Frame *f, uint32_t a0, uint32_t a1);
void istore_0(Frame *f, uint32_t a0, uint32_t a1);
void istore_1(Frame *f, uint32_t a0, uint32_t a1);
void istore_2(Frame *f, uint32_t a0, uint32_t a1);
void istore_3(Frame *f, uint32_t a0, uint32_t a1);
void iload(Frame *f, uint32_t a0, uint32_t a1);
void iload_0(Frame *f, uint32_t a0, uint32_t a1);
void iload_1(Frame *f, uint32_t a0, uint32_t a1);
void iload_2(Frame *f, uint32_t a0, uint32_t a1);
void iload_3(Frame *f, uint32_t a0, uint32_t a1);
void isub(Frame *f, uint32_t a0, uint32_t a1);
void iadd(Frame *f, uint32_t a0, uint32_t a1);
void idiv(Frame *f, uint32_t a0, uint32_t a1);
void imul(Frame *f, uint32_t a0, uint32_t a1);
void iand(Frame *f, uint32_t a0, uint32_t a1);
void ior(Frame *f, uint32_t a0, uint32_t a1);
void ishr(Frame *f, uint32_t a0, uint32_t a1);
void ishl(Frame *f, uint32_t a0, uint32_t a1);
void iushr(Frame *f, uint32_t a0, uint32_t a1);
void irem(Frame *f, uint32_t a0, uint32_t a1);
void ineg(Frame *f, uint32_t a0, uint32_t a1);
void return_func(Frame *f, uint32_t a0, uint32_t a1);
void ireturn(Frame *f, uint32_t a0, uint32_t a1);
void dreturn(Frame *f, uint32_t a0, uint32_t a1);
void lreturn(Frame *f, uint32_t a0, uint32_t a1);
void freturn(Frame *f, uint32_t a0, uint32_t a1);
void invokevirtual(Frame *f, uint32_t a0, uint32_t a1);
void invokestatic(Frame *f, uint32_t a0, uint32_t a1);
/**
* Passes the arguments from the caller to the callee's local variables array
* @param jvm pointer to jvm
* @param caller pointer to caller's frame
* @param type callee's type descriptor
*/
void jvm_set_args(JVM *jvm, Frame *caller, char *type);
void invokespecial(Frame *f, uint32_t a0, uint32_t a1);
void getstatic(Frame *f, uint32_t a0, uint32_t a1);
void putstatic(Frame *f, uint32_t a0, uint32_t a1);
/**
* Returns reference to static variable with name belonging to classname
* A null pointer is returned if not such static variable is found.
* @param jvm pointer to jvm containing static variable
* @param classname name of the class to which the variable belongs
* @param name name of the static variable
*/
Static *jvm_get_static(JVM *jvm, char *classname, char *name);
/**
* Returns reference to a newly allocted static variable.
* The newly allocated static variable is placed in the jvm's static variables stats.
* It persists until the jvm is deallocated.
* @param jvm pointer to jvm containing static variable
*/
Static *jvm_push_static(JVM *jvm);
void ldc_w(Frame *f, uint32_t a0, uint32_t a1);
void ldc2_w(Frame *f, uint32_t a0, uint32_t a1);
void dstore(Frame *f, uint32_t a0, uint32_t a1);
void dstore_0(Frame *f, uint32_t a0, uint32_t a1);
void dstore_1(Frame *f, uint32_t a0, uint32_t a1);
void dstore_2(Frame *f, uint32_t a0, uint32_t a1);
void dstore_3(Frame *f, uint32_t a0, uint32_t a1);
void dload(Frame *f, uint32_t a0, uint32_t a1);
void dload_0(Frame *f, uint32_t a0, uint32_t a1);
void dload_1(Frame *f, uint32_t a0, uint32_t a1);
void dload_2(Frame *f, uint32_t a0, uint32_t a1);
void dload_3(Frame *f, uint32_t a0, uint32_t a1);
void dadd(Frame *f, uint32_t a0, uint32_t a1);
void dsub(Frame *f, uint32_t a0, uint32_t a1);
void ddiv(Frame *f, uint32_t a0, uint32_t a1);
void dmul(Frame *f, uint32_t a0, uint32_t a1);
void dneg(Frame *f, uint32_t a0, uint32_t a1);
void drem(Frame *f, uint32_t a0, uint32_t a1);
void bipush(Frame *f, uint32_t a0, uint32_t a1);
void iconst_0(Frame *f, uint32_t a0, uint32_t a1);
void iconst_1(Frame *f, uint32_t a0, uint32_t a1);
void iconst_2(Frame *f, uint32_t a0, uint32_t a1);
void iconst_3(Frame *f, uint32_t a0, uint32_t a1);
void iconst_4(Frame *f, uint32_t a0, uint32_t a1);
void iconst_5(Frame *f, uint32_t a0, uint32_t a1);
void iconst_m1(Frame *f, uint32_t a0, uint32_t a1);
void if_icmpeq(Frame *f, uint32_t a0, uint32_t a1);
void if_icmpne(Frame *f, uint32_t a0, uint32_t a1);
void if_icmplt(Frame *f, uint32_t a0, uint32_t a1);
void if_icmpge(Frame *f, uint32_t a0, uint32_t a1);
void if_icmpgt(Frame *f, uint32_t a0, uint32_t a1);
void if_icmple(Frame *f, uint32_t a0, uint32_t a1);
void lconst_0(Frame *f, uint32_t a0, uint32_t a1);
void lconst_1(Frame *f, uint32_t a0, uint32_t a1);
void lstore(Frame *f, uint32_t a0, uint32_t a1);
void lstore_0(Frame *f, uint32_t a0, uint32_t a1);
void lstore_1(Frame *f, uint32_t a0, uint32_t a1);
void lstore_2(Frame *f, uint32_t a0, uint32_t a1);
void lstore_3(Frame *f, uint32_t a0, uint32_t a1);
void lload(Frame *f, uint32_t a0, uint32_t a1);
void lload_0(Frame *f, uint32_t a0, uint32_t a1);
void lload_1(Frame *f, uint32_t a0, uint32_t a1);
void lload_2(Frame *f, uint32_t a0, uint32_t a1);
void lload_3(Frame *f, uint32_t a0, uint32_t a1);
void ladd(Frame *f, uint32_t a0, uint32_t a1);
void lsub(Frame *f, uint32_t a0, uint32_t a1);
void lmul(Frame *f, uint32_t a0, uint32_t a1);
void ldiv_(Frame *f, uint32_t a0, uint32_t a1);
void iinc(Frame *f, uint32_t a0, uint32_t a1);
void goto_func(Frame *f, uint32_t a0, uint32_t a1);
void fconst_0(Frame *f, uint32_t a0, uint32_t a1);
void fconst_1(Frame *f, uint32_t a0, uint32_t a1);
void fconst_2(Frame *f, uint32_t a0, uint32_t a1);
void fstore(Frame *f, uint32_t a0, uint32_t a1);
void fstore_0(Frame *f, uint32_t a0, uint32_t a1);
void fstore_1(Frame *f, uint32_t a0, uint32_t a1);
void fstore_2(Frame *f, uint32_t a0, uint32_t a1);
void fstore_3(Frame *f, uint32_t a0, uint32_t a1);
void fload(Frame *f, uint32_t a0, uint32_t a1);
void fload_0(Frame *f, uint32_t a0, uint32_t a1);
void fload_1(Frame *f, uint32_t a0, uint32_t a1);
void fload_2(Frame *f, uint32_t a0, uint32_t a1);
void fload_3(Frame *f, uint32_t a0, uint32_t a1);
void fsub(Frame *f, uint32_t a0, uint32_t a1);
void fadd(Frame *f, uint32_t a0, uint32_t a1);
void fdiv(Frame *f, uint32_t a0, uint32_t a1);
void fmul(Frame *f, uint32_t a0, uint32_t a1);
void fneg(Frame *f, uint32_t a0, uint32_t a1);
void frem(Frame *f, uint32_t a0, uint32_t a1);
void ifeq(Frame *f, uint32_t a0, uint32_t a1);
void ifne(Frame *f, uint32_t a0, uint32_t a1);
void iflt(Frame *f, uint32_t a0, uint32_t a1);
void ifge(Frame *f, uint32_t a0, uint32_t a1);
void ifgt(Frame *f, uint32_t a0, uint32_t a1);
void ifle(Frame *f, uint32_t a0, uint32_t a1);
void ifnull(Frame *f, uint32_t a0, uint32_t a1);
void ifnonnull(Frame *f, uint32_t a0, uint32_t a1);
void i2f(Frame *f, uint32_t a0, uint32_t a1);
void i2d(Frame *f, uint32_t a0, uint32_t a1);
void i2b(Frame *f, uint32_t a0, uint32_t a1);
void i2c(Frame *f, uint32_t a0, uint32_t a1);
void i2l(Frame *f, uint32_t a0, uint32_t a1);
void i2s(Frame *f, uint32_t a0, uint32_t a1);
void sipush(Frame *f, uint32_t a0, uint32_t a1);
int tableswitch(JVM *jvm);
void aconst_null(Frame *f, uint32_t a0, uint32_t a);
void aload(Frame *f, uint32_t a0, uint32_t a1);
void aload_0(Frame *f, uint32_t a0, uint32_t a1);
void aload_1(Frame *f, uint32_t a0, uint32_t a1);
void aload_2(Frame *f, uint32_t a0, uint32_t a1);
void aload_3(Frame *f, uint32_t a0, uint32_t a1);
void astore(Frame *f, uint32_t a0, uint32_t a1);
void astore_0(Frame *f, uint32_t a0, uint32_t a1);
void astore_1(Frame *f, uint32_t a0, uint32_t a1);
void astore_2(Frame *f, uint32_t a0, uint32_t a1);
void astore_3(Frame *f, uint32_t a0, uint32_t a1);
void newarray(Frame *f, uint32_t a0, uint32_t a1);
void aastore(Frame *f, uint32_t a0, uint32_t a1);
void aaload(Frame *f, uint32_t a0, uint32_t a1);
void iastore(Frame *f, uint32_t a0, uint32_t a1);
void iaload(Frame *f, uint32_t a0, uint32_t a1);
void fastore(Frame *f, uint32_t a0, uint32_t a1);
void faload(Frame *f, uint32_t a0, uint32_t a1);
void lastore(Frame *f, uint32_t a0, uint32_t a1);
void laload(Frame *f, uint32_t a0, uint32_t a1);
void dastore(Frame *f, uint32_t a0, uint32_t a1);
void daload(Frame *f, uint32_t a0, uint32_t a1);
void bastore(Frame *f, uint32_t a0, uint32_t a1);
void baload(Frame *f, uint32_t a0, uint32_t a1);
void d2f(Frame *f, uint32_t a0, uint32_t a1);
void d2i(Frame *f, uint32_t a0, uint32_t a1);
void d2l(Frame *f, uint32_t a0, uint32_t a1);
void f2d(Frame *f, uint32_t a0, uint32_t a1);
void f2i(Frame *f, uint32_t a0, uint32_t a1);
void f2l(Frame *f, uint32_t a0, uint32_t a1);
void l2d(Frame *f, uint32_t a0, uint32_t a1);
void l2f(Frame *f, uint32_t a0, uint32_t a1);
void l2i(Frame *f, uint32_t a0, uint32_t a1);
void athrow(Frame *f, uint32_t a0, uint32_t a1);
void multianewarray(Frame *f, uint32_t a0, uint32_t a1);
extern operation optable[N_OPS];
/**
* Allocates 2d array and places it in jvm's heap.
* @param jvm pointer to jvm
* @param counts array of length 2 containig length of each of the 2 dimensions
* @param size size of each of the array's elements
*/
void jvm_alloc_array_2d(JVM *jvm, int32_t counts[], uint32_t size);
/**
* Allocates 3d array and places it in jvm's heap.
* @param jvm pointer to jvm
* @param counts array of length 3 containig length of each of the 3 dimensions
* @param size size of each of the array's elements
*/
void jvm_alloc_array_3d(JVM *jvm, int32_t counts[], uint32_t size);
void anewarray(Frame *f, uint32_t a0, uint32_t a1);
void dup(Frame *f, uint32_t a0, uint32_t a1);
void new(Frame *f, uint32_t a0, uint32_t a1);
void getfield(Frame *f, uint32_t a0, uint32_t a1);
void putfield(Frame *f, uint32_t a0, uint32_t a1);
/**
* Returns a index to the field 'fieldname' in class 'classname' if found in jvm's MethodArea.
* -1 is returned if the field is not found.
* @param jvm pointer to jvm
* @param classname name of the class to which the field belongs
* @param fieldname name of the field
*/
int32_t jvm_get_field_index(JVM *jvm, char *classname, char *fieldname);
/**
* Returns a reference to the field 'fieldname' in class 'classname' descriptor string.
* NULL is returned if the field is not found.
* @param jvm pointer to jvm
* @param classname name of the class to which the field belongs
* @param fieldname name of the field
*/
char *jvm_get_field_descriptor(JVM *jvm, char *classname, char *fieldname);
/**
* Allocates new object of class 'classname' and places it onto the jvm's heap.
* The object persists until the jvm is deinitialized.
* The newly allocated object contains the number of fields corresponding to
* instances of the class.
* Each field is a union that can contain one of the primitive values or a reference.
* @param jvm pointer to jvm
* @param classname name of the class
*/
void jvm_alloc_object(JVM *jvm, char *classname);