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