1
0
forked from ground/ground-old

Fix segfaults returning objects from extlibs

This commit is contained in:
2026-03-14 14:47:14 +11:00
parent 6fecf42e0e
commit e3a0f16d2e
2 changed files with 48 additions and 16 deletions

View File

@@ -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) {

View File

@@ -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) {