diff options
-rw-r--r-- | include/ucode/types.h | 25 | ||||
-rw-r--r-- | types.c | 16 |
2 files changed, 31 insertions, 10 deletions
diff --git a/include/ucode/types.h b/include/ucode/types.h index d1e01a1..314dbc8 100644 --- a/include/ucode/types.h +++ b/include/ucode/types.h @@ -47,7 +47,7 @@ typedef enum uc_type { typedef struct uc_value { uint32_t type:4; uint32_t mark:1; - uint32_t u64:1; + uint32_t u64_or_constant:1; uint32_t refcount:26; } uc_value_t; @@ -448,7 +448,28 @@ ucv_is_arrowfn(uc_value_t *uv) static inline bool ucv_is_u64(uc_value_t *uv) { - return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64 == true); + return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64_or_constant == true && + uv->type == UC_INTEGER); +} + +static inline bool +ucv_is_constant(uc_value_t *uv) +{ + return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64_or_constant == true && + (uv->type == UC_ARRAY || uv->type == UC_OBJECT)); +} + +static inline bool +ucv_set_constant(uc_value_t *uv, bool constant) +{ + if (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64_or_constant != constant && + (uv->type == UC_ARRAY || uv->type == UC_OBJECT)) { + uv->u64_or_constant = constant; + + return true; + } + + return false; } static inline bool @@ -470,7 +470,7 @@ ucv_int64_new(int64_t n) integer = xalloc(sizeof(*integer)); integer->header.type = UC_INTEGER; integer->header.refcount = 1; - integer->header.u64 = 0; + integer->header.u64_or_constant = 0; integer->i.s64 = n; return &integer->header; @@ -492,7 +492,7 @@ ucv_uint64_new(uint64_t n) integer = xalloc(sizeof(*integer)); integer->header.type = UC_INTEGER; integer->header.refcount = 1; - integer->header.u64 = 1; + integer->header.u64_or_constant = 1; integer->i.u64 = n; return &integer->header; @@ -520,7 +520,7 @@ ucv_uint64_get(uc_value_t *uv) case UC_INTEGER: integer = (uc_integer_t *)uv; - if (integer->header.u64) + if (integer->header.u64_or_constant) return integer->i.u64; if (integer->i.s64 >= 0) @@ -574,10 +574,10 @@ ucv_int64_get(uc_value_t *uv) case UC_INTEGER: integer = (uc_integer_t *)uv; - if (integer->header.u64 && integer->i.u64 <= (uint64_t)INT64_MAX) + if (integer->header.u64_or_constant && integer->i.u64 <= (uint64_t)INT64_MAX) return (int64_t)integer->i.u64; - if (!integer->header.u64) + if (!integer->header.u64_or_constant) return integer->i.s64; errno = ERANGE; @@ -715,7 +715,7 @@ ucv_array_push(uc_value_t *uv, uc_value_t *item) { uc_array_t *array = (uc_array_t *)uv; - if (ucv_type(uv) != UC_ARRAY) + if (ucv_type(uv) != UC_ARRAY || uv->u64_or_constant) return NULL; ucv_array_set(uv, array->count, item); @@ -899,7 +899,7 @@ ucv_object_add(uc_value_t *uv, const char *key, uc_value_t *val) unsigned long hash; void *k; - if (ucv_type(uv) != UC_OBJECT) + if (ucv_type(uv) != UC_OBJECT || uv->u64_or_constant) return false; hash = lh_get_hash(object->table, (const void *)key); @@ -932,7 +932,7 @@ ucv_object_delete(uc_value_t *uv, const char *key) { uc_object_t *object = (uc_object_t *)uv; - if (ucv_type(uv) != UC_OBJECT) + if (ucv_type(uv) != UC_OBJECT || uv->u64_or_constant) return false; return (lh_table_delete(object->table, key) == 0); |