#define _POSIX_C_SOURCE 200809L #include "runtime.h" #include "../utils/safe_alloc.h" #include #include static inline uint32_t _rava_field_hash(const char *name) { uint32_t hash = 5381; while (*name) { hash = ((hash << 5) + hash) ^ (uint32_t)*name++; } return hash; } RavaObject_t* rava_object_create(const char *class_name) { RavaObject_t *obj = calloc(1, sizeof(RavaObject_t)); if (!obj) return NULL; obj->class_name = strdup(class_name); obj->field_capacity = 8; obj->field_names = calloc(obj->field_capacity, sizeof(char*)); obj->field_values = calloc(obj->field_capacity, sizeof(RavaValue_t)); if (!obj->field_names || !obj->field_values) { free(obj->field_names); free(obj->field_values); free(obj->class_name); free(obj); return NULL; } obj->field_count = 0; for (int i = 0; i < RAVA_OBJECT_HASH_SIZE; i++) { obj->field_hash[i] = -1; } return obj; } void rava_object_destroy(RavaObject_t *obj) { if (!obj) return; free(obj->class_name); for (size_t i = 0; i < obj->field_count; i++) { free(obj->field_names[i]); } free(obj->field_names); free(obj->field_values); free(obj); } void rava_object_set_field(RavaObject_t *obj, const char *name, RavaValue_t value) { if (!obj || !name) return; uint32_t hash = _rava_field_hash(name); for (size_t probe = 0; probe < RAVA_OBJECT_HASH_SIZE; probe++) { uint32_t idx = (hash + probe) & (RAVA_OBJECT_HASH_SIZE - 1); int field_idx = obj->field_hash[idx]; if (field_idx == -1) { if (obj->field_count >= obj->field_capacity) { size_t new_cap = obj->field_capacity * 2; char **new_names = rava_safe_realloc(obj->field_names, new_cap * sizeof(char*)); RavaValue_t *new_values = rava_safe_realloc(obj->field_values, new_cap * sizeof(RavaValue_t)); if (!new_names || !new_values) return; obj->field_names = new_names; obj->field_values = new_values; obj->field_capacity = new_cap; } obj->field_names[obj->field_count] = strdup(name); obj->field_values[obj->field_count] = value; obj->field_hash[idx] = (int)obj->field_count; obj->field_count++; return; } if ((size_t)field_idx < obj->field_count && strcmp(obj->field_names[field_idx], name) == 0) { obj->field_values[field_idx] = value; return; } } } RavaValue_t rava_object_get_field(RavaObject_t *obj, const char *name) { if (!obj || !name) return rava_value_null(); uint32_t hash = _rava_field_hash(name); for (size_t probe = 0; probe < RAVA_OBJECT_HASH_SIZE; probe++) { uint32_t idx = (hash + probe) & (RAVA_OBJECT_HASH_SIZE - 1); int field_idx = obj->field_hash[idx]; if (field_idx == -1) { return rava_value_null(); } if ((size_t)field_idx < obj->field_count && strcmp(obj->field_names[field_idx], name) == 0) { return obj->field_values[field_idx]; } } return rava_value_null(); } int rava_object_get_field_index(RavaObject_t *obj, const char *name) { if (!obj || !name) return -1; uint32_t hash = _rava_field_hash(name); for (size_t probe = 0; probe < RAVA_OBJECT_HASH_SIZE; probe++) { uint32_t idx = (hash + probe) & (RAVA_OBJECT_HASH_SIZE - 1); int field_idx = obj->field_hash[idx]; if (field_idx == -1) return -1; if ((size_t)field_idx < obj->field_count && strcmp(obj->field_names[field_idx], name) == 0) { return field_idx; } } return -1; } RavaValue_t rava_object_get_field_by_index(RavaObject_t *obj, int index) { if (!obj || index < 0 || (size_t)index >= obj->field_count) { return rava_value_null(); } return obj->field_values[index]; } void rava_object_set_field_by_index(RavaObject_t *obj, int index, RavaValue_t value) { if (!obj || index < 0 || (size_t)index >= obj->field_count) return; obj->field_values[index] = value; }