#ifndef IMB3_VALUE_H #define IMB3_VALUE_H #include #include #include /** * Declared "for real" in gc.h. */ struct object; struct value { uintptr_t bits; }; enum value_tag { /** * A big integer or the nil constant. */ TAG_BIGINT_OR_NIL = 0b000, /** * Fixnums, i.e. integers that are stored directly in the value rather than * being pointed to. This is a two-bit tag rather than a three-bit tag... */ TAG_FIXNUM = 0b01, /** * A builtin-object. */ TAG_BUILTIN_OBJECT = 0b010, /** * A simple-array, i.e. an array of values without a fill-pointer. */ TAG_SIMPLE_ARRAY = 0b100, /** * A standard-object, effectively a pair of a class and a slot array. */ TAG_STANDARD_OBJECT = 0b110, /** * An tag that is _invalid_ for values, but may be used by the internals of * the garbage collector. */ TAG_GC_INTERNAL = 0b111, }; /** * The nil constant. */ static const struct value NIL = {.bits = 0}; /** * Allocates a builtin-object with the given class and slot count. */ struct value alloc_builtin_object(struct value class, size_t value_slot_count, size_t untraced_slot_count); /** * Stores an intptr_t as a fixnum or a bignum. */ struct value integer_of_int(intptr_t); /** * Returns the tag of a value. */ enum value_tag get_tag(struct value); /** * Returns whether a value is a pointer. */ bool is_ptr(struct value); /** * Tags a pointer. */ struct value tag_ptr(struct object *, enum value_tag); /** * Untags a fixnum. */ intptr_t untag_fixnum(struct value); /** * Untags a pointer. */ struct object *untag_ptr(struct value); /** * Bootstraps the class heirarchy. This should only be called once. */ void bootstrap(void); #endif // IMB3_VALUE_H