MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix crash with upvalues

+40 -20
+6 -1
include/gc/objects.h
··· 6 6 7 7 #define ANT_GC_DEAD 0xFF 8 8 9 - typedef void (*gc_str_mark_fn)(ant_t *js, ant_value_t v); 9 + typedef void (*gc_str_mark_fn)( 10 + ant_t *js, 11 + ant_value_t v 12 + ); 13 + 14 + uint64_t gc_get_epoch(void); 10 15 bool gc_obj_is_marked(const ant_object_t *obj); 11 16 12 17 void gc_mark_value(ant_t *js, ant_value_t v);
+5 -1
include/silver/engine.h
··· 5 5 #include "internal.h" 6 6 #include "runtime.h" 7 7 #include "errors.h" 8 + #include "gc/objects.h" 8 9 9 10 #include <stdbool.h> 10 11 #include <stdint.h> ··· 249 250 #define SV_CALL_HAS_SUPER (1u << 1) 250 251 #define SV_CALL_IS_ARROW (1u << 2) 251 252 #define SV_CALL_IS_DEFAULT_CTOR (1u << 3) 253 + #define SV_CALL_BORROWED_UPVALS (1u << 4) 252 254 253 255 typedef struct sv_closure { 254 256 uint32_t call_flags; ··· 266 268 } sv_closure_t; 267 269 268 270 static inline sv_closure_t *js_closure_alloc(ant_t *js) { 269 - return (sv_closure_t *)fixed_arena_alloc(&js->closure_arena); 271 + sv_closure_t *c = (sv_closure_t *)fixed_arena_alloc(&js->closure_arena); 272 + if (c) c->gc_epoch = gc_get_epoch(); 273 + return c; 270 274 } 271 275 272 276 static inline sv_closure_t *js_func_closure(ant_value_t func) {
+6 -2
src/ant.c
··· 4564 4564 ant_value_t func = mkval(T_FUNC, (uintptr_t)closure); 4565 4565 ant_value_t proto_setup = setup_func_prototype(js, func); 4566 4566 if (is_err(proto_setup)) return proto_setup; 4567 + 4567 4568 return func; 4568 4569 } 4569 4570 ··· 4789 4790 sv_closure_t *orig = js_func_closure(func); 4790 4791 sv_closure_t *bound_closure = js_closure_alloc(js); 4791 4792 if (!bound_closure) return js_mkerr(js, "oom"); 4793 + 4792 4794 bound_closure->func = orig->func; 4795 + bound_closure->call_flags = orig->call_flags; 4793 4796 bound_closure->upvalues = orig->upvalues; 4797 + if (orig->upvalues) bound_closure->call_flags |= SV_CALL_BORROWED_UPVALS; 4794 4798 bound_closure->bound_this = this_arg; 4795 4799 bound_closure->bound_args = js_mkundef(); 4796 4800 bound_closure->super_val = orig->super_val; 4797 4801 bound_closure->func_obj = bound_func; 4798 - bound_closure->call_flags = orig->call_flags; 4802 + 4799 4803 if (bound_argc > 0) 4800 4804 bound_closure->call_flags |= SV_CALL_HAS_BOUND_ARGS; 4801 4805 ··· 4840 4844 4841 4845 ant_value_t bound = mkval(T_FUNC, (uintptr_t)bound_closure); 4842 4846 ant_value_t proto_setup = setup_func_prototype(js, bound); 4847 + 4843 4848 if (is_err(proto_setup)) return proto_setup; 4844 - 4845 4849 js_mark_constructor(bound_func, js_is_constructor(js, func)); 4846 4850 4847 4851 return bound;
+17 -9
src/gc/objects.c
··· 648 648 ant_ic_epoch_bump(); 649 649 gc_promote_survivors(js); 650 650 651 - 652 651 ant_fixed_arena_t *ca = &js->closure_arena; 653 652 ca->free_list = NULL; 654 653 ca->live_count = 0; 654 + 655 655 for (size_t off = 0; off < ca->watermark; off += ca->elem_size) { 656 - sv_closure_t *c = (sv_closure_t *)(ca->base + off); 657 - if (c->gc_epoch == gc_epoch) ca->live_count++; 658 - else { 656 + sv_closure_t *c = (sv_closure_t *)(ca->base + off); 657 + 658 + if (c->gc_epoch == gc_epoch) ca->live_count++; 659 + else { 660 + if (!(c->call_flags & SV_CALL_BORROWED_UPVALS)) { 659 661 free(c->upvalues); 660 662 c->upvalues = NULL; 661 - free(c->bound_argv); 662 - c->bound_argv = NULL; 663 - *(void **)c = ca->free_list; 664 - ca->free_list = c; 665 663 } 666 - } 664 + 665 + free(c->bound_argv); 666 + c->bound_argv = NULL; 667 + 668 + *(void **)c = ca->free_list; 669 + ca->free_list = c; 670 + }} 667 671 668 672 ant_fixed_arena_t *ua = &js->upvalue_arena; 669 673 ua->free_list = NULL; ··· 741 745 // gc_epoch would not be updated and they would be incorrectly freed. 742 746 // closure/upvalue arenas are only swept on major GC `gc_objects_run` 743 747 } 748 + 749 + uint64_t gc_get_epoch(void) { 750 + return gc_epoch; 751 + }
+1 -1
src/silver/ops/comparison.h
··· 1 1 #ifndef SV_COMPARISON_H 2 2 #define SV_COMPARISON_H 3 3 4 - #include "silver/engine.h" 5 4 #include "shapes.h" 5 + #include "silver/engine.h" 6 6 #include "modules/bigint.h" 7 7 8 8 static inline void sv_op_seq(sv_vm_t *vm, ant_t *js) {
+5 -6
src/silver/ops/upvalues.h
··· 109 109 } 110 110 } 111 111 112 + ant_value_t func_val = mkval(T_FUNC, (uintptr_t)closure); 113 + vm->stack[vm->sp++] = func_val; 114 + 112 115 ant_value_t func_obj = mkobj(js, 0); 113 116 closure->func_obj = func_obj; 117 + 114 118 js_mark_constructor(func_obj, !child->is_arrow && !child->is_method); 115 119 js_setprop(js, func_obj, js->length_str, tov((double)child->param_count)); 116 120 js_set_descriptor(js, func_obj, "length", 6, JS_DESC_C); 117 121 118 - ant_value_t func_val = mkval(T_FUNC, (uintptr_t)closure); 119 122 if (!child->is_arrow && !child->is_method) sv_setup_function_prototype(js, func_obj, func_val); 120 - 121 - if (child->is_strict) 122 - js_set_slot(func_obj, SLOT_STRICT, js_true); 123 + if (child->is_strict) js_set_slot(func_obj, SLOT_STRICT, js_true); 123 124 124 125 if (child->is_async) { 125 126 js_set_slot(func_obj, SLOT_ASYNC, js_true); ··· 129 130 ant_value_t func_proto = js_get_slot(js->global, SLOT_FUNC_PROTO); 130 131 if (vtype(func_proto) == T_FUNC) js_set_proto_init(func_obj, func_proto); 131 132 } 132 - 133 - vm->stack[vm->sp++] = func_val; 134 133 } 135 134 136 135 #endif