Skip to content

Commit

Permalink
Small but important improvements
Browse files Browse the repository at this point in the history
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
  • Loading branch information
marcobambini committed Dec 5, 2018
1 parent 8b5bc31 commit 5f8f3d2
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 30 deletions.
46 changes: 19 additions & 27 deletions src/runtime/gravity_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down
10 changes: 9 additions & 1 deletion src/runtime/gravity_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/shared/gravity_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
14 changes: 14 additions & 0 deletions src/shared/gravity_value.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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: -
Expand Down
5 changes: 3 additions & 2 deletions src/shared/gravity_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 5f8f3d2

Please sign in to comment.