From fd5b237dfe415d3c4e388489d52a7a31b8f08dad Mon Sep 17 00:00:00 2001 From: William Bell <62452284+Ugric@users.noreply.github.com> Date: Mon, 1 Sep 2025 23:09:09 +0100 Subject: [PATCH] set up so reusing scope when in a loop --- anonymous-function-test.ar | 2 +- src/runtime/internals/hashmap/hashmap.c | 7 +++++++ src/runtime/internals/hashmap/hashmap.h | 2 ++ src/runtime/objects/object.c | 2 +- src/runtime/objects/object.h | 1 + src/runtime/objects/string/string.c | 2 +- src/runtime/runtime.c | 4 ++++ src/translator/bytecode_spec.md | 4 ++++ src/translator/translator.h | 1 + src/translator/while/while.c | 6 +++--- 10 files changed, 25 insertions(+), 6 deletions(-) diff --git a/anonymous-function-test.ar b/anonymous-function-test.ar index c7b039e..2c929db 100644 --- a/anonymous-function-test.ar +++ b/anonymous-function-test.ar @@ -1,3 +1,3 @@ -let i = 10000000 +let i = 1e7 while (i) do i=i-1 \ No newline at end of file diff --git a/src/runtime/internals/hashmap/hashmap.c b/src/runtime/internals/hashmap/hashmap.c index ce6fe9a..ef71d11 100644 --- a/src/runtime/internals/hashmap/hashmap.c +++ b/src/runtime/internals/hashmap/hashmap.c @@ -21,9 +21,16 @@ struct hashmap_GC *createHashmap_GC() { t->order = 1; t->list = (struct node_GC **)ar_alloc(sizeof(struct node_GC *) * size); memset(t->list, 0, sizeof(struct node_GC *) * size); + t->count = 0; return t; } +void clear_hashmap_GC(struct hashmap_GC *t) { + t->order = 1; + t->count = 0; + memset(t->list, 0, sizeof(struct node_GC *) * t->size); +} + void resize_hashmap_GC(struct hashmap_GC *t) { int old_size = t->size; int new_size = old_size * 2; diff --git a/src/runtime/internals/hashmap/hashmap.h b/src/runtime/internals/hashmap/hashmap.h index 5271206..e2043de 100644 --- a/src/runtime/internals/hashmap/hashmap.h +++ b/src/runtime/internals/hashmap/hashmap.h @@ -25,6 +25,8 @@ struct hashmap_GC { struct hashmap_GC *createHashmap_GC(); +void clear_hashmap_GC(struct hashmap_GC *t); + int hashCode_GC(struct hashmap_GC *t, uint64_t hash); int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash); diff --git a/src/runtime/objects/object.c b/src/runtime/objects/object.c index e85509c..b0bd36b 100644 --- a/src/runtime/objects/object.c +++ b/src/runtime/objects/object.c @@ -20,7 +20,7 @@ const char *built_in_field_names[BUILT_IN_FIELDS_COUNT] = { "__string__", "__subtract__", "__multiply__", "__division__", "__new__", "__init__", "__boolean__", "__get_attr__", "__binding__", "__function__", "address", "__call__", - "__number__", "log"}; + "__number__", "log", "length"}; uint64_t built_in_field_hashes[BUILT_IN_FIELDS_COUNT]; diff --git a/src/runtime/objects/object.h b/src/runtime/objects/object.h index 4b097f8..1e6e1cc 100644 --- a/src/runtime/objects/object.h +++ b/src/runtime/objects/object.h @@ -30,6 +30,7 @@ typedef enum { __call__, __number__, field_log, + field_length, BUILT_IN_FIELDS_COUNT } built_in_fields; diff --git a/src/runtime/objects/string/string.c b/src/runtime/objects/string/string.c index 19c9fa6..cf0980f 100644 --- a/src/runtime/objects/string/string.c +++ b/src/runtime/objects/string/string.c @@ -17,7 +17,7 @@ ArgonObject *new_string_object(char *data, size_t length, uint64_t prehash, uint64_t hash) { ArgonObject *object = new_object(); add_builtin_field(object, __class__, ARGON_STRING_TYPE); - add_builtin_field(object, length, + add_builtin_field(object, field_length, new_number_object_from_num_and_den(length, 1)); object->type = TYPE_STRING; object->value.as_str.data = ar_alloc_atomic(length); diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 2d0047a..fca1a97 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -683,6 +683,7 @@ static inline void run_instructions(Translated *translated, RuntimeState *state, [OP_JUMP_IF_FALSE] = &&DO_JUMP_IF_FALSE, [OP_JUMP] = &&DO_JUMP, [OP_NEW_SCOPE] = &&DO_NEW_SCOPE, + [OP_EMPTY_SCOPE] = &&DO_EMPTY_SCOPE, [OP_POP_SCOPE] = &&DO_POP_SCOPE, [OP_INIT_CALL] = &&DO_INIT_CALL, [OP_INSERT_ARG] = &&DO_INSERT_ARG, @@ -745,6 +746,9 @@ DO_JUMP: DO_NEW_SCOPE: *stack = create_scope(*stack); goto START; +DO_EMPTY_SCOPE: + clear_hashmap_GC((*stack)->scope); + goto START; DO_POP_SCOPE: *stack = (*stack)->prev; goto START; diff --git a/src/translator/bytecode_spec.md b/src/translator/bytecode_spec.md index 9495985..1dc2ad2 100644 --- a/src/translator/bytecode_spec.md +++ b/src/translator/bytecode_spec.md @@ -93,6 +93,10 @@ jumps unconditionally to an index. creates a new stack +## OP_EMPTY_SCOPE + +empties the current scope so the same memory can be reused. + ## OP_POP_SCOPE pops the top scope off the current diff --git a/src/translator/translator.h b/src/translator/translator.h index 69322d0..774d49d 100644 --- a/src/translator/translator.h +++ b/src/translator/translator.h @@ -24,6 +24,7 @@ typedef enum { OP_JUMP_IF_FALSE, OP_JUMP, OP_NEW_SCOPE, + OP_EMPTY_SCOPE, OP_POP_SCOPE, OP_INIT_CALL, OP_INSERT_ARG, diff --git a/src/translator/while/while.c b/src/translator/while/while.c index a98de51..2787abb 100644 --- a/src/translator/while/while.c +++ b/src/translator/while/while.c @@ -18,7 +18,7 @@ size_t translate_parsed_while(Translated *translated, ParsedWhile *parsedWhile, translated->return_jumps = &return_jumps; } size_t first = push_instruction_byte(translated, OP_NEW_SCOPE); - translate_parsed(translated, parsedWhile->condition, err); + size_t start_of_loop = translate_parsed(translated, parsedWhile->condition, err); if (err->exists) { return 0; } @@ -28,9 +28,9 @@ size_t translate_parsed_while(Translated *translated, ParsedWhile *parsedWhile, push_instruction_byte(translated, 0); uint64_t jump_index = push_instruction_code(translated, 0); translate_parsed(translated, parsedWhile->content, err); - push_instruction_byte(translated, OP_POP_SCOPE); + push_instruction_byte(translated, OP_EMPTY_SCOPE); push_instruction_byte(translated, OP_JUMP); - push_instruction_code(translated, first); + push_instruction_code(translated, start_of_loop);