forked from ground/ground
Fix segfaults returning objects from extlibs
This commit is contained in:
@@ -43,66 +43,76 @@ GroundValue groundCreateValue(GroundValueType type, ...) {
|
|||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, type);
|
va_start(args, type);
|
||||||
|
|
||||||
|
GroundValue gv;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case INT: {
|
case INT: {
|
||||||
return createIntGroundValue(va_arg(args, int64_t));
|
gv = createIntGroundValue(va_arg(args, int64_t));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DOUBLE: {
|
case DOUBLE: {
|
||||||
return createDoubleGroundValue(va_arg(args, double));
|
gv = createDoubleGroundValue(va_arg(args, double));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STRING: {
|
case STRING: {
|
||||||
return createStringGroundValue(va_arg(args, char*));
|
gv = createStringGroundValue(va_arg(args, char*));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CHAR: {
|
case CHAR: {
|
||||||
return createCharGroundValue((char)va_arg(args, int));
|
gv = createCharGroundValue((char)va_arg(args, int));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BOOL: {
|
case BOOL: {
|
||||||
return createBoolGroundValue((bool)va_arg(args, int));
|
gv = createBoolGroundValue((bool)va_arg(args, int));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LIST: {
|
case LIST: {
|
||||||
return createListGroundValue(va_arg(args, List));
|
gv = createListGroundValue(va_arg(args, List));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FUNCTION: {
|
case FUNCTION: {
|
||||||
return createFunctionGroundValue(va_arg(args, GroundFunction*));
|
gv = createFunctionGroundValue(va_arg(args, GroundFunction*));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STRUCTVAL: {
|
case STRUCTVAL: {
|
||||||
GroundValue gv;
|
|
||||||
gv.type = STRUCTVAL;
|
gv.type = STRUCTVAL;
|
||||||
gv.data.structVal = malloc(sizeof(GroundStruct));
|
gv.data.structVal = malloc(sizeof(GroundStruct));
|
||||||
*gv.data.structVal = va_arg(args, GroundStruct);
|
*gv.data.structVal = va_arg(args, GroundStruct);
|
||||||
return gv;
|
break;
|
||||||
}
|
}
|
||||||
case NONE: {
|
case NONE: {
|
||||||
return createNoneGroundValue();
|
gv = createNoneGroundValue();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CUSTOM: {
|
case CUSTOM: {
|
||||||
// CUSTOM values are created from structs
|
// CUSTOM values are created from structs
|
||||||
GroundValue gv;
|
|
||||||
GroundStruct* gstruct = va_arg(args, GroundStruct*);
|
GroundStruct* gstruct = va_arg(args, GroundStruct*);
|
||||||
gv.type = CUSTOM;
|
gv.type = CUSTOM;
|
||||||
gv.data.customVal = malloc(sizeof(GroundObject));
|
gv.data.customVal = malloc(sizeof(GroundObject));
|
||||||
*gv.data.customVal = createObject(*gstruct);
|
*gv.data.customVal = createObject(*gstruct);
|
||||||
gv.customType = gstruct;
|
|
||||||
|
// Deep copy the struct definition so it stays valid
|
||||||
|
gv.customType = malloc(sizeof(GroundStruct));
|
||||||
|
gv.customType->size = gstruct->size;
|
||||||
|
gv.customType->fields = malloc(gstruct->size * sizeof(GroundStructField));
|
||||||
|
for (size_t i = 0; i < gstruct->size; i++) {
|
||||||
|
strncpy(gv.customType->fields[i].id, gstruct->fields[i].id, 64);
|
||||||
|
gv.customType->fields[i].value = copyGroundValue(&gstruct->fields[i].value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ERROR: {
|
case ERROR: {
|
||||||
// FIXME
|
// FIXME
|
||||||
return createNoneGroundValue();
|
gv = createNoneGroundValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
gv = createNoneGroundValue();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return createNoneGroundValue();
|
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
return gv;
|
||||||
}
|
}
|
||||||
|
|
||||||
GroundValue groundRunProgram(GroundProgram* program) {
|
GroundValue groundRunProgram(GroundProgram* program) {
|
||||||
|
|||||||
24
src/types.c
24
src/types.c
@@ -128,7 +128,6 @@ GroundValue copyGroundValue(const GroundValue* gv) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CUSTOM: {
|
case CUSTOM: {
|
||||||
newGv.customType = gv->customType;
|
|
||||||
newGv.data.customVal = malloc(sizeof(GroundObject));
|
newGv.data.customVal = malloc(sizeof(GroundObject));
|
||||||
if (newGv.data.customVal == NULL) {
|
if (newGv.data.customVal == NULL) {
|
||||||
printf("Couldn't allocate memory for GroundObject copy\n");
|
printf("Couldn't allocate memory for GroundObject copy\n");
|
||||||
@@ -137,6 +136,15 @@ GroundValue copyGroundValue(const GroundValue* gv) {
|
|||||||
|
|
||||||
newGv.data.customVal->fields = NULL;
|
newGv.data.customVal->fields = NULL;
|
||||||
|
|
||||||
|
// Deep copy the struct definition as well
|
||||||
|
newGv.customType = malloc(sizeof(GroundStruct));
|
||||||
|
newGv.customType->size = gv->customType->size;
|
||||||
|
newGv.customType->fields = malloc(gv->customType->size * sizeof(GroundStructField));
|
||||||
|
for (size_t i = 0; i < gv->customType->size; i++) {
|
||||||
|
strncpy(newGv.customType->fields[i].id, gv->customType->fields[i].id, 64);
|
||||||
|
newGv.customType->fields[i].value = copyGroundValue(&gv->customType->fields[i].value);
|
||||||
|
}
|
||||||
|
|
||||||
GroundObjectField *field, *tmp;
|
GroundObjectField *field, *tmp;
|
||||||
HASH_ITER(hh, gv->data.customVal->fields, field, tmp) {
|
HASH_ITER(hh, gv->data.customVal->fields, field, tmp) {
|
||||||
GroundObjectField* newField = malloc(sizeof(GroundObjectField));
|
GroundObjectField* newField = malloc(sizeof(GroundObjectField));
|
||||||
@@ -267,6 +275,20 @@ void freeGroundValue(GroundValue* gv) {
|
|||||||
freeGroundStruct(gstruct);
|
freeGroundStruct(gstruct);
|
||||||
free(gstruct);
|
free(gstruct);
|
||||||
}
|
}
|
||||||
|
if (gv->type == CUSTOM && gv->data.customVal != NULL) {
|
||||||
|
freeGroundObject(gv->data.customVal);
|
||||||
|
free(gv->data.customVal);
|
||||||
|
gv->data.customVal = NULL;
|
||||||
|
|
||||||
|
if (gv->customType != NULL) {
|
||||||
|
for (size_t i = 0; i < gv->customType->size; i++) {
|
||||||
|
freeGroundValue(&gv->customType->fields[i].value);
|
||||||
|
}
|
||||||
|
free(gv->customType->fields);
|
||||||
|
free(gv->customType);
|
||||||
|
gv->customType = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (gv->type == ERROR) {
|
if (gv->type == ERROR) {
|
||||||
GroundError* error = &gv->data.errorVal;
|
GroundError* error = &gv->data.errorVal;
|
||||||
if (error->type != NULL) {
|
if (error->type != NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user