2026-07-03 15:14:41 +10:00
|
|
|
#include "../../include/ground.h"
|
2026-07-13 11:49:59 +10:00
|
|
|
#include <string.h>
|
2026-07-03 15:14:41 +10:00
|
|
|
|
|
|
|
|
GroundBytecodeValue _GroundCopyBytecodeValue(GroundBytecodeValue* value) {
|
|
|
|
|
GroundBytecodeValue newValue = *value;
|
|
|
|
|
switch (value->type.type) {
|
|
|
|
|
case GroundType_Int:
|
|
|
|
|
case GroundType_Double:
|
|
|
|
|
case GroundType_Bool:
|
|
|
|
|
case GroundType_Char:
|
2026-07-13 11:49:59 +10:00
|
|
|
case GroundType_CoreType:
|
2026-07-03 15:14:41 +10:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GroundType_String: {
|
|
|
|
|
newValue.as.String = Ground.Copy.String(&value->as.String);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-13 11:49:59 +10:00
|
|
|
case GroundType_Object: {
|
|
|
|
|
GroundBytecodeObject* src = &value->as.Object;
|
|
|
|
|
GroundBytecodeObject dst = {
|
|
|
|
|
.size = src->size,
|
|
|
|
|
.capacity = src->capacity,
|
|
|
|
|
};
|
|
|
|
|
if (src->capacity > 0) {
|
|
|
|
|
dst.values = malloc(sizeof(GroundBytecodeValue) * src->capacity);
|
|
|
|
|
if (dst.values == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (GroundSize i = 0; i < src->size; i++) {
|
|
|
|
|
dst.values[i] = Ground.Copy.BytecodeValue(&src->values[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
newValue.as.Object = dst;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case GroundType_Struct: {
|
|
|
|
|
GroundBytecodeStruct* src = &value->as.Struct;
|
|
|
|
|
GroundBytecodeStruct dst = {
|
|
|
|
|
.size = src->size,
|
|
|
|
|
.capacity = src->capacity,
|
|
|
|
|
};
|
|
|
|
|
if (src->capacity > 0) {
|
|
|
|
|
dst.values = malloc(sizeof(GroundBytecodeValue) * src->capacity);
|
|
|
|
|
if (dst.values == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (GroundSize i = 0; i < src->size; i++) {
|
|
|
|
|
dst.values[i] = Ground.Copy.BytecodeValue(&src->values[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
newValue.as.Struct = dst;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case GroundType_List: {
|
|
|
|
|
GroundBytecodeList* src = &value->as.List;
|
|
|
|
|
GroundBytecodeList dst = {
|
|
|
|
|
.count = src->count,
|
|
|
|
|
.capacity = src->capacity,
|
|
|
|
|
};
|
|
|
|
|
if (src->capacity > 0) {
|
|
|
|
|
dst.at = malloc(sizeof(GroundBytecodeValue) * src->capacity);
|
|
|
|
|
if (dst.at == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (GroundSize i = 0; i < src->count; i++) {
|
|
|
|
|
dst.at[i] = Ground.Copy.BytecodeValue(&src->at[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
newValue.as.List = dst;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case GroundType_Function: {
|
|
|
|
|
GroundBytecodeFunction* src = &value->as.Function;
|
|
|
|
|
GroundBytecodeFunction dst = *src;
|
|
|
|
|
|
|
|
|
|
if (src->args.at != NULL && src->args.count > 0) {
|
|
|
|
|
dst.args.at = malloc(sizeof(GroundFunctionArg) * src->args.count);
|
|
|
|
|
if (dst.args.at == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
memcpy(dst.args.at, src->args.at, sizeof(GroundFunctionArg) * src->args.count);
|
|
|
|
|
} else {
|
|
|
|
|
dst.args.at = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!src->isNativeFunction && src->program.ground != NULL) {
|
|
|
|
|
dst.program.ground = malloc(sizeof(GroundBytecodeProgram));
|
|
|
|
|
if (dst.program.ground == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
free(dst.args.at);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
*dst.program.ground = *src->program.ground;
|
|
|
|
|
if (src->program.ground->at != NULL && src->program.ground->len > 0) {
|
|
|
|
|
dst.program.ground->at = malloc(sizeof(GroundBytecodeInstruction) * src->program.ground->len);
|
|
|
|
|
if (dst.program.ground->at == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
free(dst.program.ground);
|
|
|
|
|
free(dst.args.at);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (GroundSize i = 0; i < src->program.ground->len; i++) {
|
|
|
|
|
dst.program.ground->at[i] = src->program.ground->at[i];
|
|
|
|
|
if (src->program.ground->at[i].args.at != NULL && src->program.ground->at[i].args.len > 0) {
|
|
|
|
|
dst.program.ground->at[i].args.at = malloc(sizeof(GroundSize) * src->program.ground->at[i].args.len);
|
|
|
|
|
if (dst.program.ground->at[i].args.at == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
memcpy(dst.program.ground->at[i].args.at, src->program.ground->at[i].args.at, sizeof(GroundSize) * src->program.ground->at[i].args.len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (src->closure != NULL) {
|
|
|
|
|
dst.closure = malloc(sizeof(GroundBytecodeHeap));
|
|
|
|
|
if (dst.closure == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
dst.closure->capacity = src->closure->capacity;
|
|
|
|
|
dst.closure->len = src->closure->len;
|
|
|
|
|
if (src->closure->heap != NULL && src->closure->len > 0) {
|
|
|
|
|
dst.closure->heap = malloc(sizeof(GroundBytecodeValue) * src->closure->capacity);
|
|
|
|
|
if (dst.closure->heap == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
free(dst.closure);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (GroundSize i = 0; i < src->closure->len; i++) {
|
|
|
|
|
if (src->closure->heap[i].type.type == GroundType_Function) {
|
|
|
|
|
dst.closure->heap[i] = src->closure->heap[i];
|
|
|
|
|
} else {
|
|
|
|
|
dst.closure->heap[i] = Ground.Copy.BytecodeValue(&src->closure->heap[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
dst.closure->heap = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (src->isNativeFunction && src->returnType != NULL) {
|
|
|
|
|
dst.returnType = malloc(sizeof(GroundType));
|
|
|
|
|
if (dst.returnType == NULL) {
|
|
|
|
|
Ground.Log.Error("malloc failed in Ground.Copy.BytecodeValue");
|
|
|
|
|
Ground.Flags.error = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
*dst.returnType = *src->returnType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newValue.as.Function = dst;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-03 15:14:41 +10:00
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newValue;
|
|
|
|
|
}
|