Browse Source

Small but important improvements

Fixed an issue in convert_map2string
Added gravity_vm_reset function (only used in Creo so far)
Added a way for the bridge to be called when an object needs to be blacken by GC
Marco Bambini 6 năm trước cách đây
mục cha
commit
5f8f3d2c15

+ 19 - 27
src/runtime/gravity_core.c

@@ -174,42 +174,38 @@ static inline gravity_value_t convert_map2string (gravity_vm *vm, gravity_map_t
 
     // get keys list
     uint32_t count = gravity_hash_count(map->hash);
-    gravity_list_t *list = gravity_list_new(NULL, count);
+    gravity_list_t *list = gravity_list_new(vm, count);
     gravity_hash_iterate(map->hash, map_keys_array, (void *)list);
 
     count = (uint32_t) marray_size(list->array);
     for (uint32_t i=0; i<count; ++i) {
         gravity_value_t key = marray_get(list->array, i);
-        gravity_value_t *v = gravity_hash_lookup(map->hash, key);
-        gravity_value_t value = (v) ? *v : VALUE_FROM_NULL;
-        gravity_value_t value_converted = VALUE_FROM_NULL;
-
-        gravity_string_t *svalue;
-        gravity_string_t *skey;
-        bool key_to_free = false;
-        bool value_to_free = false;
+        gravity_value_t *valueptr = gravity_hash_lookup(map->hash, key);
+        gravity_value_t value = (valueptr) ? *valueptr : VALUE_FROM_NULL;
         
+        // key conversion
         if (!VALUE_ISA_STRING(key)) {
-            key = convert_value2string(NULL, key);
-            key_to_free = true;
+            key = convert_value2string(vm, key);
         }
-        skey = (VALUE_ISA_STRING(key)) ? VALUE_AS_STRING(key) : NULL;
-
+        gravity_string_t *key_string = (VALUE_ISA_STRING(key)) ? VALUE_AS_STRING(key) : NULL;
+        
+        // value conversion
         if (VALUE_ISA_MAP(value) && (VALUE_AS_MAP(value) == map)) {
-            svalue = NULL;
-        } else {
-            value_converted = convert_value2string(NULL, value);
-            value_to_free = true;
-            svalue = VALUE_ISA_VALID(value_converted) ? VALUE_AS_STRING(value_converted) : NULL;
+            // to avoid infinite loop
+            value = VALUE_FROM_NULL;
         }
-
+        if (!VALUE_ISA_STRING(value)) {
+            value = convert_value2string(vm, value);
+        }
+        gravity_string_t *value_string = (VALUE_ISA_STRING(value)) ? VALUE_AS_STRING(value) : NULL;
+        
         // KEY
-        char *s1 = (skey) ? skey->s : "N/A";
-        uint32_t len1 = (skey) ? skey->len : 3;
+        char *s1 = (key_string) ? key_string->s : "N/A";
+        uint32_t len1 = (key_string) ? key_string->len : 3;
 
         // VALUE
-        char *s2 = (svalue) ? svalue->s : "N/A";
-        uint32_t len2 = (svalue) ? svalue->len : 3;
+        char *s2 = (value_string) ? value_string->s : "N/A";
+        uint32_t len2 = (value_string) ? value_string->len : 3;
 
         // check if buffer needs to be reallocated
         if (len1 + len2 + pos + 4 > len) {
@@ -234,16 +230,12 @@ static inline gravity_value_t convert_map2string (gravity_vm *vm, gravity_map_t
             memcpy(buffer+pos, ",", 1);
             pos += 1;
         }
-        
-        if (key_to_free && skey) gravity_value_free(NULL, key);
-        if (value_to_free && svalue) gravity_value_free(NULL, value_converted);
     }
 
     // Write latest ] character
     memcpy(buffer+pos, "]", 1);
     buffer[++pos] = 0;
 
-    gravity_list_free(NULL, list);
     gravity_value_t result = VALUE_FROM_STRING(vm, buffer, pos);
     mem_free(buffer);
     return result;

+ 9 - 1
src/runtime/gravity_vm.c

@@ -1712,11 +1712,17 @@ bool gravity_vm_runmain (gravity_vm *vm, gravity_closure_t *closure) {
     return result;
 }
 
+void gravity_vm_reset (gravity_vm *vm) {
+    if (!vm || !vm->fiber) return;
+    gravity_fiber_reset(vm->fiber);
+}
+
 // MARK: - User -
 
 gravity_closure_t *gravity_vm_getclosure (gravity_vm *vm) {
-    if (!vm->fiber) return NULL;
+    if (!vm || !vm->fiber) return NULL;
     if (!vm->fiber->nframes) return NULL;
+    if (vm->aborted) return NULL;
 
     gravity_callframe_t *frame = &(vm->fiber->frames[vm->fiber->nframes-1]);
     return frame->closure;
@@ -2120,6 +2126,7 @@ static void gravity_gc_transfer_object (gravity_vm *vm, gravity_object_t *obj) {
 static void gravity_gc_transfer (gravity_vm *vm, gravity_object_t *obj) {
     if (vm->gcenabled > 0) {
         #if GRAVITY_GC_STRESSTEST
+        #if 0
         // check if ptr is already in the list
         gravity_object_t **ptr = &vm->gchead;
         while (*ptr) {
@@ -2129,6 +2136,7 @@ static void gravity_gc_transfer (gravity_vm *vm, gravity_object_t *obj) {
             }
             ptr = &(*ptr)->gc.next;
         }
+        #endif
         gravity_gc_start(vm);
         #else
         if (vm->memallocated >= vm->gcthreshold) gravity_gc_start(vm);

+ 2 - 0
src/shared/gravity_delegate.h

@@ -53,6 +53,7 @@ typedef const char*         (*gravity_bridge_string) (gravity_vm *vm, void *xdat
 typedef void*               (*gravity_bridge_clone)  (gravity_vm *vm, void *xdata);
 typedef uint32_t            (*gravity_bridge_size) (gravity_vm *vm, gravity_object_t *obj);
 typedef void                (*gravity_bridge_free) (gravity_vm *vm, gravity_object_t *obj);
+typedef void                (*gravity_bridge_blacken) (gravity_vm *vm, void *xdata);
 
 typedef struct {
     // user data
@@ -78,6 +79,7 @@ typedef struct {
     gravity_bridge_setundef     bridge_setundef;        // setter not found
     gravity_bridge_getundef     bridge_getundef;        // getter not found
     gravity_bridge_execute      bridge_execute;         // execute a method/function
+    gravity_bridge_blacken      bridge_blacken;         // blacken obj to be GC friend
     gravity_bridge_string       bridge_string;          // instance string conversion
     gravity_bridge_equals       bridge_equals;          // check if two objects are equals
     gravity_bridge_clone        bridge_clone;           // clone

+ 14 - 0
src/shared/gravity_value.c

@@ -1352,6 +1352,14 @@ void gravity_fiber_reassign (gravity_fiber_t *fiber, gravity_closure_t *closure,
     fiber->stacktop += FN_COUNTREG(closure->f, nargs);
 }
 
+void gravity_fiber_reset (gravity_fiber_t *fiber) {
+    fiber->caller = NULL;
+    fiber->result = VALUE_FROM_NULL;
+    fiber->nframes = 0;
+    fiber->upvalues = NULL;
+    fiber->stacktop = fiber->stack;
+}
+
 void gravity_fiber_seterror (gravity_fiber_t *fiber, const char *error) {
     if (fiber->error) mem_free(fiber->error);
     fiber->error = (char *)string_dup(error);
@@ -1666,6 +1674,12 @@ void gravity_instance_blacken (gravity_vm *vm, gravity_instance_t *i) {
     for (uint32_t j=0; j<i->objclass->nivars; ++j) {
         gravity_gray_value(vm, i->ivars[j]);
     }
+    
+    // xdata
+    if (i->xdata) {
+        gravity_delegate_t *delegate = gravity_vm_delegate(vm);
+        if (delegate->bridge_blacken) delegate->bridge_blacken(vm, i->xdata);
+    }
 }
 
 // MARK: -

+ 3 - 2
src/shared/gravity_value.h

@@ -66,8 +66,8 @@
 extern "C" {
 #endif
 
-#define GRAVITY_VERSION						"0.5.8"     // git tag 0.5.8
-#define GRAVITY_VERSION_NUMBER				0x000508    // git push --tags
+#define GRAVITY_VERSION						"0.5.9"     // git tag 0.5.9
+#define GRAVITY_VERSION_NUMBER				0x000509    // git push --tags
 #define GRAVITY_BUILD_DATE                  __DATE__
 
 #ifndef GRAVITY_ENABLE_DOUBLE
@@ -479,6 +479,7 @@ GRAVITY_API uint32_t            gravity_class_size (gravity_vm *vm, gravity_clas
 GRAVITY_API gravity_fiber_t     *gravity_fiber_new (gravity_vm *vm, gravity_closure_t *closure, uint32_t nstack, uint32_t nframes);
 GRAVITY_API void                gravity_fiber_reassign (gravity_fiber_t *fiber, gravity_closure_t *closure, uint16_t nargs);
 GRAVITY_API void                gravity_fiber_seterror (gravity_fiber_t *fiber, const char *error);
+GRAVITY_API void                gravity_fiber_reset (gravity_fiber_t *fiber);
 GRAVITY_API void                gravity_fiber_free (gravity_vm *vm, gravity_fiber_t *fiber);
 GRAVITY_API void                gravity_fiber_blacken (gravity_vm *vm, gravity_fiber_t *fiber);
 GRAVITY_API uint32_t            gravity_fiber_size (gravity_vm *vm, gravity_fiber_t *fiber);