From 9db69f8012a24950cec87ce9f62947eb7cfda94d Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Thu, 31 Oct 2019 21:37:47 -0700 Subject: [PATCH] Implement DUP_U2, SP_INC, DELETE, R_ASSIGN Reference assignment. --- ain.h | 17 +++++++++++++++++ instructions.c | 10 +++++----- test/Source/lang.jaf | 8 ++++++++ vm.c | 32 +++++++++++++++++++++++++++++++- 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/ain.h b/ain.h index 30e3e16..d993eea 100644 --- a/ain.h +++ b/ain.h @@ -79,6 +79,23 @@ enum ain_data_type { case AIN_ARRAY_LONG_INT: \ case AIN_ARRAY_DELEGATE +#define AIN_REF_TYPE \ + AIN_REF_INT: \ + case AIN_REF_FLOAT: \ + case AIN_REF_STRING: \ + case AIN_REF_STRUCT: \ + case AIN_REF_ARRAY_INT: \ + case AIN_REF_ARRAY_FLOAT: \ + case AIN_REF_ARRAY_STRING: \ + case AIN_REF_ARRAY_STRUCT: \ + case AIN_REF_FUNC_TYPE: \ + case AIN_REF_ARRAY_FUNC_TYPE: \ + case AIN_REF_BOOL: \ + case AIN_REF_ARRAY_BOOL: \ + case AIN_REF_LONG_INT: \ + case AIN_REF_ARRAY_LONG_INT: \ + case AIN_REF_ARRAY_DELEGATE + struct ain_variable { char *name; int32_t data_type; diff --git a/instructions.c b/instructions.c index 20b6d55..e0cc999 100644 --- a/instructions.c +++ b/instructions.c @@ -155,9 +155,9 @@ const struct instruction instructions[NR_OPCODES] = { OP(I_STRING, 0), JMP(CALLFUNC2, 0), OP(DUP2_X1, 0), - OP(R_ASSIGN, 0), // TODO + OP(R_ASSIGN, 0), OP(FT_ASSIGNS, 0), // TODO - OP(ASSERT, 0), // TODO + OP(ASSERT, 0), OP(S_LT, 0), OP(S_GT, 0), OP(S_LTE, 0), @@ -165,12 +165,12 @@ const struct instruction instructions[NR_OPCODES] = { OP(S_LENGTH2, 0), // TODO OP(S_LENGTHBYTE2, 0), // TODO OP(NEW, 0), // TODO - OP(DELETE, 0), // TODO + OP(DELETE, 0), OP(CHECKUDO, 0), // TODO OP(A_REF, 0), OP(DUP, 0), - OP(DUP_U2, 0), // TODO - OP(SP_INC, 0), // TODO + OP(DUP_U2, 0), + OP(SP_INC, 0), OP(SP_DEC, 0), // TODO OP(ENDFUNC, 1, INSTR_FUN), OP(R_EQUALE, 0), // TODO diff --git a/test/Source/lang.jaf b/test/Source/lang.jaf index 115f9be..c0eadb2 100755 --- a/test/Source/lang.jaf +++ b/test/Source/lang.jaf @@ -90,6 +90,13 @@ int test_string_switch_default(string s) return -1; } +ref int gi; + +void set_page_ref(int v) +{ + gi <- v; +} + void test_lang(void) { int i; @@ -112,4 +119,5 @@ void test_lang(void) test_equal("string switch", test_string_switch("b"), 1); test_equal("string switch (no default)", test_string_switch("d"), 100); test_equal("string switch (default)", test_string_switch_default("d"), 100); + test_equal("local ref escape", (set_page_ref(42), gi), 42); } diff --git a/vm.c b/vm.c index a86a481..1f44724 100644 --- a/vm.c +++ b/vm.c @@ -210,7 +210,7 @@ static union vm_value *stack_pop_var(void) int32_t page_index = stack_pop().i; int32_t heap_index = stack_pop().i; if (!heap[heap_index].page || page_index >= heap[heap_index].page->nr_vars) - EXECUTION_ERROR("Out of bounds page index"); + EXECUTION_ERROR("Out of bounds page index: %d/%d", heap_index, page_index); return &heap[heap_index].page->values[page_index]; } @@ -320,6 +320,10 @@ static void system_call(int32_t code) case 0x0: // system.Exit(int nResult) sys_exit(stack_pop().i); break; + case 0x3: // system.LockPeek() + case 0x4: // system.UnlockPeek() + stack_push(1); + break; case 0x6: // system.Output(string szText) str = stack_peek_string(0); utf = sjis2utf(str->text, str->size); @@ -432,11 +436,18 @@ static void execute_instruction(int16_t opcode) stack_push(b); stack_push(c); break; + case DUP_U2: + // AB -> ABA + stack_push(stack_peek(1).i); + break; case SWAP: a = stack_peek(1).i; stack_set(1, stack_peek(0)); stack_set(0, a); break; + // + // --- Variables --- + // case PUSHGLOBALPAGE: stack_push(0); break; @@ -481,6 +492,23 @@ static void execute_instruction(int16_t opcode) case SH_LOCALCREATE: // VARNO, STRUCTNO create_struct(get_argument(1), local_ptr(get_argument(0))); break; + case R_ASSIGN: + varno = stack_pop().i; + pageno = stack_pop().i; + dst_i = stack_pop().i; + dst = stack_pop().i; + heap[dst].page->values[dst_i].i = pageno; + heap[dst].page->values[dst_i+1].i = varno; + stack_push(pageno); + stack_push(varno); + break; + case DELETE: + if ((slot = stack_pop().i) != -1) + heap_unref(slot); + break; + case SP_INC: + heap_ref(stack_pop().i); + break; // // --- Control Flow --- // @@ -1028,6 +1056,8 @@ void vm_execute_ain(struct ain *program) case AIN_STRING: heap[0].page->values[i].i = heap_alloc_slot(VM_STRING); break; + case AIN_REF_TYPE: + heap[0].page->values[i].i = -1; default: break; }