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_start(args, type);
|
||||
|
||||
GroundValue gv;
|
||||
switch (type) {
|
||||
case INT: {
|
||||
return createIntGroundValue(va_arg(args, int64_t));
|
||||
gv = createIntGroundValue(va_arg(args, int64_t));
|
||||
break;
|
||||
}
|
||||
case DOUBLE: {
|
||||
return createDoubleGroundValue(va_arg(args, double));
|
||||
gv = createDoubleGroundValue(va_arg(args, double));
|
||||
break;
|
||||
}
|
||||
case STRING: {
|
||||
return createStringGroundValue(va_arg(args, char*));
|
||||
gv = createStringGroundValue(va_arg(args, char*));
|
||||
break;
|
||||
}
|
||||
case CHAR: {
|
||||
return createCharGroundValue((char)va_arg(args, int));
|
||||
gv = createCharGroundValue((char)va_arg(args, int));
|
||||
break;
|
||||
}
|
||||
case BOOL: {
|
||||
return createBoolGroundValue((bool)va_arg(args, int));
|
||||
gv = createBoolGroundValue((bool)va_arg(args, int));
|
||||
break;
|
||||
}
|
||||
case LIST: {
|
||||
return createListGroundValue(va_arg(args, List));
|
||||
gv = createListGroundValue(va_arg(args, List));
|
||||
break;
|
||||
}
|
||||
case FUNCTION: {
|
||||
return createFunctionGroundValue(va_arg(args, GroundFunction*));
|
||||
gv = createFunctionGroundValue(va_arg(args, GroundFunction*));
|
||||
break;
|
||||
}
|
||||
case STRUCTVAL: {
|
||||
GroundValue gv;
|
||||
gv.type = STRUCTVAL;
|
||||
gv.data.structVal = malloc(sizeof(GroundStruct));
|
||||
*gv.data.structVal = va_arg(args, GroundStruct);
|
||||
return gv;
|
||||
break;
|
||||
}
|
||||
case NONE: {
|
||||
return createNoneGroundValue();
|
||||
gv = createNoneGroundValue();
|
||||
break;
|
||||
}
|
||||
case CUSTOM: {
|
||||
// CUSTOM values are created from structs
|
||||
GroundValue gv;
|
||||
GroundStruct* gstruct = va_arg(args, GroundStruct*);
|
||||
gv.type = CUSTOM;
|
||||
gv.data.customVal = malloc(sizeof(GroundObject));
|
||||
*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;
|
||||
}
|
||||
case ERROR: {
|
||||
// FIXME
|
||||
return createNoneGroundValue();
|
||||
gv = createNoneGroundValue();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
gv = createNoneGroundValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return createNoneGroundValue();
|
||||
|
||||
va_end(args);
|
||||
return gv;
|
||||
}
|
||||
|
||||
GroundValue groundRunProgram(GroundProgram* program) {
|
||||
|
||||
24
src/types.c
24
src/types.c
@@ -128,7 +128,6 @@ GroundValue copyGroundValue(const GroundValue* gv) {
|
||||
break;
|
||||
}
|
||||
case CUSTOM: {
|
||||
newGv.customType = gv->customType;
|
||||
newGv.data.customVal = malloc(sizeof(GroundObject));
|
||||
if (newGv.data.customVal == NULL) {
|
||||
printf("Couldn't allocate memory for GroundObject copy\n");
|
||||
@@ -137,6 +136,15 @@ GroundValue copyGroundValue(const GroundValue* gv) {
|
||||
|
||||
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;
|
||||
HASH_ITER(hh, gv->data.customVal->fields, field, tmp) {
|
||||
GroundObjectField* newField = malloc(sizeof(GroundObjectField));
|
||||
@@ -267,6 +275,20 @@ void freeGroundValue(GroundValue* gv) {
|
||||
freeGroundStruct(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) {
|
||||
GroundError* error = &gv->data.errorVal;
|
||||
if (error->type != NULL) {
|
||||
|
||||
Reference in New Issue
Block a user