instruction init
This commit is contained in:
parent
0def8039e1
commit
5fc36bc7f7
42
classfile.c
42
classfile.c
@ -1,4 +1,5 @@
|
|||||||
#include "classfile.h"
|
#include "classfile.h"
|
||||||
|
#include "instruction.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -359,18 +360,18 @@ ClassFile* ClassFile_load(const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClassFile_info(const ClassFile* cf) {
|
void ClassFile_info(const ClassFile* cf) {
|
||||||
printf(
|
printf("Metadata:\n"
|
||||||
"magic=%X\n"
|
"\tmagic=%X\n"
|
||||||
"minor_version=%hu\n"
|
"\tminor_version=%hu\n"
|
||||||
"major_version=%hu\n"
|
"\tmajor_version=%hu\n"
|
||||||
"constant_pool_count=%hu\n"
|
"\tconstant_pool_count=%hu\n"
|
||||||
"access_flags=%hx\n"
|
"\taccess_flags=%hx\n"
|
||||||
"this_class=%hu\n"
|
"\tthis_class=%hu\n"
|
||||||
"super_class=%hu\n"
|
"\tsuper_class=%hu\n"
|
||||||
"interfaces_count=%hu\n"
|
"\tinterfaces_count=%hu\n"
|
||||||
"fields_count=%hu\n"
|
"\tfields_count=%hu\n"
|
||||||
"methods_count=%hu\n"
|
"\tmethods_count=%hu\n"
|
||||||
"attributes_count=%hu\n",
|
"\tattributes_count=%hu\n\n",
|
||||||
cf->magic, cf->minor_version, cf->major_version, cf->constant_pool_count, cf->access_flags, cf->this_class, cf->super_class, cf->interfaces_count,
|
cf->magic, cf->minor_version, cf->major_version, cf->constant_pool_count, cf->access_flags, cf->this_class, cf->super_class, cf->interfaces_count,
|
||||||
cf->fields_count, cf->methods_count, cf->attributes_count);
|
cf->fields_count, cf->methods_count, cf->attributes_count);
|
||||||
|
|
||||||
@ -426,7 +427,7 @@ void ClassFile_info(const ClassFile* cf) {
|
|||||||
buffer);
|
buffer);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
default:
|
default:
|
||||||
putchar('\n');
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,7 +436,7 @@ void ClassFile_info(const ClassFile* cf) {
|
|||||||
char* super_name =
|
char* super_name =
|
||||||
cf->super_class != 0 ? (char*)cf->constant_pool[cf->constant_pool[cf->super_class - 1].info.class_info.name_index - 1].info.utf8_info.bytes : NULL;
|
cf->super_class != 0 ? (char*)cf->constant_pool[cf->constant_pool[cf->super_class - 1].info.class_info.name_index - 1].info.utf8_info.bytes : NULL;
|
||||||
char* type = (cf->access_flags & ACC_INTERFACE ? "interface" : (cf->access_flags & ACC_ENUM ? "enum" : (cf->access_flags & ACC_MODULE ? "module" : "class")));
|
char* type = (cf->access_flags & ACC_INTERFACE ? "interface" : (cf->access_flags & ACC_ENUM ? "enum" : (cf->access_flags & ACC_MODULE ? "module" : "class")));
|
||||||
printf("%s%s%s%s %s%s%s ", cf->access_flags & ACC_PUBLIC ? "public " : "", cf->access_flags & ACC_FINAL ? "final " : "",
|
printf("\n%s%s%s%s %s%s%s ", cf->access_flags & ACC_PUBLIC ? "public " : "", cf->access_flags & ACC_FINAL ? "final " : "",
|
||||||
cf->access_flags & ACC_ABSTRACT ? "abstract " : "", type, this_name, super_name ? " extends " : "", super_name ? super_name : "");
|
cf->access_flags & ACC_ABSTRACT ? "abstract " : "", type, this_name, super_name ? " extends " : "", super_name ? super_name : "");
|
||||||
|
|
||||||
// interfaces
|
// interfaces
|
||||||
@ -476,7 +477,18 @@ void ClassFile_info(const ClassFile* cf) {
|
|||||||
for (u2 j = 0; j < cf->methods[i].attributes_count; j++) {
|
for (u2 j = 0; j < cf->methods[i].attributes_count; j++) {
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(";\n");
|
printf("{\n");
|
||||||
|
|
||||||
|
// code
|
||||||
|
for (u2 j = 0; j < cf->methods[i].attributes_count; j++) {
|
||||||
|
if (cf->methods[i].attributes[j]._tag == CODE) {
|
||||||
|
Instruction* code = Instruction_parse(cf->methods[i].attributes[j].info.code_attribute.code_length, cf->methods[i].attributes[j].info.code_attribute.code);
|
||||||
|
Instruction_print_code(code);
|
||||||
|
// TODO: free code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\t}\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
typedef uint8_t u1;
|
typedef uint8_t u1;
|
||||||
typedef uint16_t u2;
|
typedef uint16_t u2;
|
||||||
typedef uint32_t u4;
|
typedef uint32_t u4;
|
||||||
|
typedef uint64_t u8;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ACC_PUBLIC = 0x0001,
|
ACC_PUBLIC = 0x0001,
|
||||||
|
65
instruction.c
Normal file
65
instruction.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include "instruction.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "classfile.h"
|
||||||
|
|
||||||
|
Instruction* Instruction_parse(uint32_t bytes_length, uint8_t* bytes) {
|
||||||
|
Instruction* start = (Instruction*)malloc(sizeof(Instruction));
|
||||||
|
Instruction* current = start;
|
||||||
|
|
||||||
|
u4 i = 0, n = 0;
|
||||||
|
|
||||||
|
while (i < bytes_length) {
|
||||||
|
current->opcode = bytes[i++];
|
||||||
|
|
||||||
|
switch (current->opcode) {
|
||||||
|
case ALOAD_0:
|
||||||
|
case RETURN:
|
||||||
|
current->operands = NULL;
|
||||||
|
break;
|
||||||
|
case LDC:
|
||||||
|
*(u1*)¤t->operands = bytes[i++];
|
||||||
|
break;
|
||||||
|
case GETSTATIC:
|
||||||
|
case INVOKESPECIAL:
|
||||||
|
case INVOKEVIRTUAL:
|
||||||
|
// current->operands = malloc(sizeof(u2));
|
||||||
|
*(u2*)¤t->operands = (*(u2*)&bytes[i] << 8) | bytes[i + 1];
|
||||||
|
i += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < bytes_length) {
|
||||||
|
current->next = (Instruction*)malloc(sizeof(Instruction));
|
||||||
|
current = current->next;
|
||||||
|
} else {
|
||||||
|
current->next = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instruction_print_code(Instruction* code) {
|
||||||
|
u4 i = 0;
|
||||||
|
while (code) {
|
||||||
|
printf("\t\t%hx ", (u1)code[i].opcode);
|
||||||
|
switch (code[i].opcode) {
|
||||||
|
case ALOAD_0:
|
||||||
|
case RETURN:
|
||||||
|
putchar('\n');
|
||||||
|
break;
|
||||||
|
case LDC:
|
||||||
|
printf("#%hhu\n", *(u1*)&code[i].operands);
|
||||||
|
break;
|
||||||
|
case GETSTATIC:
|
||||||
|
case INVOKESPECIAL:
|
||||||
|
case INVOKEVIRTUAL:
|
||||||
|
printf("#%hu\n", *(u2*)&code[i].operands);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code = code->next;
|
||||||
|
}
|
||||||
|
}
|
24
instruction.h
Normal file
24
instruction.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ALOAD_0 = 0x2a,
|
||||||
|
INVOKESPECIAL = 0xb7,
|
||||||
|
RETURN = 0xb1,
|
||||||
|
GETSTATIC = 0xb2,
|
||||||
|
LDC = 0x12,
|
||||||
|
INVOKEVIRTUAL = 0xb6,
|
||||||
|
} OPCODE;
|
||||||
|
|
||||||
|
typedef struct Instruction {
|
||||||
|
OPCODE opcode;
|
||||||
|
uint8_t* operands;
|
||||||
|
struct Instruction* next;
|
||||||
|
} Instruction;
|
||||||
|
|
||||||
|
Instruction* Instruction_parse(uint32_t bytes_length, uint8_t* bytes);
|
||||||
|
void Instruction_print_code(Instruction* code);
|
||||||
|
|
||||||
|
#pragma pack()
|
Loading…
Reference in New Issue
Block a user