From d1722c26b1aacb2fe078146a6813379500157d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammed=20Yasinhan=20Ya=C5=9Far?= Date: Mon, 19 May 2025 21:20:07 +0300 Subject: [PATCH] hsetof opcode is added for offsetted allocated garbage collectable memory setting --- include/tasm/tasm_ast.h | 7 +++++++ include/tasm/tasm_lexer.h | 6 +++--- include/tasm/tasm_parser.h | 2 ++ include/tasm/tasm_token.h | 1 + include/tasm/tasm_translator.h | 4 ++++ include/tvm/tvm.h | 32 +++++++++++++++++++++++++++++++- 6 files changed, 48 insertions(+), 4 deletions(-) diff --git a/include/tasm/tasm_ast.h b/include/tasm/tasm_ast.h index 30507f6..f8aec46 100644 --- a/include/tasm/tasm_ast.h +++ b/include/tasm/tasm_ast.h @@ -84,6 +84,7 @@ typedef struct tasm_ast{ AST_OP_DEREF, AST_OP_DEREFB, AST_OP_HSET, + AST_OP_HSETOF, AST_OP_PUTS, AST_OP_PUTC, AST_OP_NATIVE, @@ -401,6 +402,12 @@ void tasm_ast_show(tasm_ast_t* node, int indent) { case AST_OP_HALLOC: printf("HALLOC\n"); break; + case AST_OP_HSET: + printf("HSET\n"); + break; + case AST_OP_HSETOF: + printf("HSETOF\n"); + break; case AST_OP_PUTS: printf("PUTS\n"); break; diff --git a/include/tasm/tasm_lexer.h b/include/tasm/tasm_lexer.h index 4359588..a98490e 100644 --- a/include/tasm/tasm_lexer.h +++ b/include/tasm/tasm_lexer.h @@ -360,7 +360,7 @@ tasm_token_t tasm_lexer_collect_binary_number(tasm_lexer_t *lexer) { return token; } -const size_t _inst_strings_count = 62; +const size_t _inst_strings_count = 63; const char* _inst_strings_lower[] = { "nop", "push", "pop", @@ -375,7 +375,7 @@ const char* _inst_strings_lower[] = { "and", "or", "not", "band", "bor", "bnot", "lshft", "rshft", "loadc", "aloadc", "load", "store", "gload", "gstore", - "halloc", "deref", "derefb", "hset", + "halloc", "deref", "derefb", "hset", "hsetof", "puts", "putc", "native", "hlt" @@ -394,7 +394,7 @@ const char* _inst_strings_upper[] = { "AND", "OR", "NOT", "BAND", "BOR", "BNOT", "LSHFT", "RSHFT", "LOADC", "ALOADC", "LOAD", "STORE", "GLOAD", "GSTORE", - "HALLOC", "DEREF", "DEREFB", "HSET", + "HALLOC", "DEREF", "DEREFB", "HSET", "HSETOF", "PUTS", "PUTC", "NATIVE", "HLT" diff --git a/include/tasm/tasm_parser.h b/include/tasm/tasm_parser.h index f9186f2..4525769 100644 --- a/include/tasm/tasm_parser.h +++ b/include/tasm/tasm_parser.h @@ -633,6 +633,8 @@ tasm_ast_t* tasm_parse_instruction(tasm_parser_t* parser) { break; case TOKEN_OP_HSET: tag = AST_OP_HSET; break; + case TOKEN_OP_HSETOF: tag = AST_OP_HSETOF; + break; case TOKEN_OP_PUTS: tag = AST_OP_PUTS; break; case TOKEN_OP_PUTC: tag = AST_OP_PUTC; diff --git a/include/tasm/tasm_token.h b/include/tasm/tasm_token.h index 936bd94..1916e8f 100644 --- a/include/tasm/tasm_token.h +++ b/include/tasm/tasm_token.h @@ -90,6 +90,7 @@ typedef enum { TOKEN_OP_DEREF, TOKEN_OP_DEREFB, TOKEN_OP_HSET, + TOKEN_OP_HSETOF, TOKEN_OP_PUTS, TOKEN_OP_PUTC, TOKEN_OP_NATIVE, diff --git a/include/tasm/tasm_translator.h b/include/tasm/tasm_translator.h index a28a26c..64ce58f 100644 --- a/include/tasm/tasm_translator.h +++ b/include/tasm/tasm_translator.h @@ -124,6 +124,7 @@ case AST_OP_HALLOC: \ case AST_OP_DEREF: \ case AST_OP_DEREFB: \ case AST_OP_HSET: \ +case AST_OP_HSETOF: \ case AST_OP_PUTS: \ case AST_OP_PUTC: \ case AST_OP_NATIVE: \ @@ -493,6 +494,9 @@ static void tasm_translate_line(tasm_translator_t* translator, tasm_ast_t* node, case AST_OP_HSET: program_push(translator, (opcode_t){.type = OP_HSET}); break; + case AST_OP_HSETOF: + program_push(translator, (opcode_t){.type = OP_HSETOF}); + break; case AST_OP_PUTS: program_push(translator, (opcode_t){.type = OP_PUTS}); break; diff --git a/include/tvm/tvm.h b/include/tvm/tvm.h index 85af790..d0790e5 100644 --- a/include/tvm/tvm.h +++ b/include/tvm/tvm.h @@ -109,6 +109,7 @@ typedef enum { OP_DEREF, OP_DEREFB, // deref for a spesific byte-sized object OP_HSET, + OP_HSETOF, // offset version of hset /* print to standart output */ OP_PUTS, @@ -908,7 +909,7 @@ exception_t tvm_exec_opcode(tvm_t* vm) { } vm->ip++; break; - case OP_HSET: + case OP_HSET: { if (vm->sp < 4) return EXCEPT_STACK_UNDERFLOW; uint32_t byte_size = vm->stack[vm->sp - 1].i32; // byte_size @@ -940,6 +941,35 @@ exception_t tvm_exec_opcode(tvm_t* vm) { vm->sp -= 4; vm->ip++; break; + } + case OP_HSETOF: { + if (vm->sp < 4) + return EXCEPT_STACK_UNDERFLOW; + uint32_t type_size = vm->stack[vm->sp - 1].i32; // type_size + uint32_t offset = vm->stack[vm->sp - 2].i32; // offset + gc_block* addr = (gc_block*)(vm->stack[vm->sp - 3].ui64); // beginning address of the value (it should be) + + uint64_t size = addr->size; + if (offset >= size) { + return EXCEPT_INVALID_ARRAY_INDEX; // FIXME: here with a correct runtime error + } + + switch (type_size) + { +#ifdef __x86_64__ + case sizeof(uint32_t): *(uint32_t*)(addr->value + offset) = vm->stack[vm->sp - 4].ui32; break; + case sizeof(uint8_t): *(uint8_t*)(addr->value + offset) = vm->stack[vm->sp - 4].ui8; break; + case sizeof(uint64_t): *(uint64_t*)(addr->value + offset) = vm->stack[vm->sp - 4].ui64; break; +#elif defined(__i386__) + case sizeof(uint32_t): *(uint32_t*)((uint32_t*)addr->value + offset) = vm->stack[vm->sp - 4].ui32; break; + case sizeof(uint8_t): *(uint8_t*)((uint8_t*)addr->value + offset) = vm->stack[vm->sp - 4].ui8; break; +#endif + default: return EXCEPT_INVALID_PRIMITIVE_SIZE; + } + vm->sp -= 4; + vm->ip++; + break; + } case OP_PUTS: if (vm->sp < 1) return EXCEPT_STACK_UNDERFLOW;