Commit 6e597322 authored by Jeffrey J. Ma's avatar Jeffrey J. Ma
Browse files

latest

parent 9ea90cc4
No related merge requests found
Pipeline #18191 failed with stage
Showing with 409 additions and 4 deletions
+409 -4
File added
No preview for this file type
File added
File added
File added
...@@ -31,10 +31,415 @@ const char *MAIN_DESCRIPTOR = "([Ljava/lang/String;)V"; ...@@ -31,10 +31,415 @@ const char *MAIN_DESCRIPTOR = "([Ljava/lang/String;)V";
int32_t *execute(method_t *method, int32_t *locals, class_file_t *class) { int32_t *execute(method_t *method, int32_t *locals, class_file_t *class) {
/* You should remove these casts to void in your solution. /* You should remove these casts to void in your solution.
* They are just here so the code compiles without warnings. */ * They are just here so the code compiles without warnings. */
(void) method;
(void) locals; int32_t stack[method->code.max_stack];
(void) class; u2 stack_height = 0;
return NULL; u4 program_counter = 0;
while (true) {
u1 op_code = method->code.code[program_counter];
program_counter++;
switch (op_code) {
/* Part 1: 1 + 2
*
* EMPHASIS ON SIGNED BYTE
* */
case i_bipush:
stack[stack_height] = (int8_t) method->code.code[program_counter];
stack_height++;
program_counter++;
break;
case i_iadd:
stack[stack_height - 2] += stack[ stack_height - 1];
stack_height--;
break;
case i_return:
return NULL;
/* Part 2: Printing 1 + 2 */
case i_invokevirtual:
printf("%d\n", stack[stack_height - 1]);
stack_height--;
case i_getstatic:
program_counter += 2;
break;
/* Part 3: More Constant Instructions
*
* emphasis on SIGNED short FOR i_sipush
* */
case i_iconst_m1:
case i_iconst_0:
case i_iconst_1:
case i_iconst_2:
case i_iconst_3:
case i_iconst_4:
case i_iconst_5:
stack[stack_height] = op_code - i_iconst_0;
stack_height++;
break;
case i_sipush: {
u2 high_byte = method->code.code[program_counter];
program_counter++;
stack[stack_height] = (int16_t) (high_byte << 8 | method->code.code[program_counter]);
program_counter++;
stack_height++;
break;
}
/*
* Part 4: Arithmetic Operations
*
* Remind students to avoid code repitition
*/
case i_isub:
stack[stack_height - 2] -= stack[ stack_height - 1];
stack_height--;
break;
case i_imul:
stack[stack_height - 2] *= stack[ stack_height - 1];
stack_height--;
break;
case i_idiv:
stack[stack_height - 2] /= stack[ stack_height - 1];
stack_height--;
break;
case i_irem:
stack[stack_height - 2] %= stack[ stack_height - 1];
stack_height--;
break;
case i_ineg:
stack[stack_height - 1] = - stack[ stack_height - 1];
break;
/*
* Part 5: Using Local Variables
*
* Remind to avoid code repetition
*
* Remind to use stack_height -1 when trying to access top of stack
*/
case i_iload:
stack[stack_height] = locals[method->code.code[program_counter]];
program_counter++;
stack_height++;
break;
case i_istore:
locals[method->code.code[program_counter]] = stack[stack_height - 1];
program_counter++;
stack_height--;
break;
case i_iinc: {
u1 local = method->code.code[program_counter];
program_counter++;
locals[local] += (int8_t) method->code.code[program_counter++];
break;
}
case i_iload_0:
case i_iload_1:
case i_iload_2:
case i_iload_3:
stack[stack_height] = locals[op_code - i_iload_0];
stack_height++;
break;
case i_istore_0:
case i_istore_1:
case i_istore_2:
case i_istore_3:
locals[op_code - i_istore_0] = stack[stack_height - 1];
stack_height--;
break;
/*
* Part 6: Using the Constant Pool
*
* DOUBLE CHECK THIS why do we need to convert to so many different things
*/
case i_ldc: {
cp_info *constant = get_constant(&
class->constant_pool,
method->code.code[program_counter]);
program_counter++;
CONSTANT_Integer_info *int_value = (void *) constant->info;
stack[stack_height++] = int_value->bytes;
break;
}
/*
* Part 7:
*
* jump offset is -3 because we need to move pc to the point
* right before jump instruction
*/
case i_ifeq: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 1] == 0) {
program_counter += jump_offset;
}
stack_height--;
break;
}
case i_ifne: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 1] != 0) {
program_counter += jump_offset;
}
stack_height--;
break;
}
case i_iflt: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 1] < 0) {
program_counter += jump_offset;
}
stack_height--;
break;
}
case i_ifge: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 1] >= 0) {
program_counter += jump_offset;
}
stack_height--;
break;
}
case i_ifgt: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 1] > 0) {
program_counter += jump_offset;
}
stack_height--;
break;
}
case i_ifle: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 1] <= 0) {
program_counter += jump_offset;
}
stack_height--;
break;
}
case i_if_icmpeq: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 2] == stack[stack_height - 1]) {
program_counter += jump_offset;
}
stack_height-= 2;
break;
}
case i_if_icmpne: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 2] != stack[stack_height - 1]) {
program_counter += jump_offset;
}
stack_height-= 2;
break;
}
case i_if_icmplt: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 2] < stack[stack_height - 1]) {
program_counter += jump_offset;
}
stack_height-= 2;
break;
}
case i_if_icmpge: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 2] >= stack[stack_height - 1]) {
program_counter += jump_offset;
}
stack_height-= 2;
break;
}
case i_if_icmpgt: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 2] > stack[stack_height - 1]) {
program_counter += jump_offset;
}
stack_height-= 2;
break;
}
case i_if_icmple: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
if (stack[stack_height - 2] <= stack[stack_height - 1]) {
program_counter += jump_offset;
}
stack_height-= 2;
break;
}
case i_goto: {
u2 high_byte = method->code.code[program_counter++];
int16_t jump_offset = (high_byte << 8 | method->code.code[program_counter++]) - 3;
program_counter += jump_offset;
break;
}
/*
* Part 8:
*/
case i_ireturn:
int32_t *result = malloc(sizeof(*result));
*result = stack[stack_height - 1];
stack_height--; // redundant
return result;
case i_invokestatic: {
u2 high_byte = method->code.code[program_counter++];
int16_t index = (high_byte << 8 | method->code.code[program_counter++]);
// get calee
method *callee = find_method_from_index(index, class);
// setup locals array
int32_t locals[callee->code.max_locals];
// get num args
u2 num_args = get_number_of_parameters(callee);
memcpy(locals, &stack[stack_height -= num_args], sizeof(*stack) * num_args)
int32_t *result = execute(callee, locals, class);
if (result) {
free(result);
}
break;
}
}
}
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment