# The Value Type

The class `core.lang.Value` represents a value of some type that is stored inside a variable. As such, a `Value` is essentially just a reference to a `Type` in the name tree (or `void`, if the reference is `null`). It does, however, also contain the variable `ref` that indicates if the stored value is a reference to the value or not. This is used to distinguish reference and non-reference parameters in parameter lists for example. Note that `ref` is to be interpreted in addition to the usual semantics of the referred type. That is, if the `Value` refers to a class or actor type, and has its `ref` set to true, then the variable is to be considered a reference to the reference to the actual instance.

Apart from packing these two values together, the `Value` class contains a large number of convenience functions for checking properties of types. It is therefore not uncommon to cast types to a `Value` before comparing them:

- `core.Maybe<core.lang.Type> type`

  The type stored. If `null`, the value refers to `void` and the value in `ref` is meaningless.

- `core.Bool ref`

  Is this value representing a reference to `type`?

- `core.lang.Value asRef()`

  Return a copy that is a reference.

- `core.lang.Value asRef(core.Bool ref)`

  Return a copy that is a reference.

- `core.Bool mayReferTo(core.lang.Value x)`

  Check if a value of this type may refer to a value of type `x`. As the name implies, this check is performed with references in mind. As such, this is used to determine if formal parameters of a function matches actual parameters, or when figuring out if a (copy) assignment should be allowed.

  Note: `void` is considered to be able to refer to all other types.

  Note: This definition is separate from storage. Since the size of derived value types differ, it is not possible to store a derived type in a variable sized after the super type (without slicing), even if the super type may refer to the derived type.

  Note: This function was previously named 'canStore', but was split due to to the possible confusion with storage size.

- `core.Bool mayStore(core.lang.Value x)`

  See if it is possible to store a value of `x` inside a value of this type without any conversions. Works like 'mayReferTo', except that value types use strict equality, and `void` is not considered to be able to store any other types.

- `core.Bool matches(core.lang.Value v, core.lang.NamedFlags flags)`

  Does this value match another value according to NamedFlags? Works like 'mayReferTo', but flags effect the outcome. Note that this relation is not reflexive. If no special flags are set, then it is equivalent to 'mayReferTo'.

- `core.asm.Size size()`

  Return the size of this type. Respects by-reference semantics and the `ref` member. As such, always return a pointer size for classes and actors.

- `core.asm.TypeDesc desc(core.lang.Value v)`

  Get a description of this type.

- `core.asm.Operand copyCtor()`

  Get an Operand pointing to the copy constructor for this type. Only returns something useful for value types, as other types can and shall be copied using an inline mov-instruction.

- `core.asm.Operand destructor()`

  Get an Operand pointing to the destructor for this type. May return Operand(), meaning no destructor is needed.

There are also a number of utility functions available:

- `core.lang.Value thisPtr(core.lang.Type t)`

  Create a this pointer for a type.

- `core.lang.Value common(core.lang.Value a, core.lang.Value b)`

  Compute the common denominator of two values so that it is possible to cast both 'a' and 'b' to the resulting type. In case 'a' and 'b' are unrelated, Value() - void is returned.

Apart from the above functions for comparing types, the `Value` class also provides information related to code generation.

- `core.Bool returnInReg()`

  Should this type be returned in a register? Note: we count `void` as being returned in a register.

- `core.Bool isValue()`

  Does this value refer to a value-type? Either `isValue` or `isObject` returns true for non-void types.

- `core.Bool isObject()`

  Does this value refer to a heap-allocated type (i.e. a class or an actor)? Either `isValue` or `isObject` returns true for non-void types.

- `core.Bool isClass()`

  Is this a class type?

- `core.Bool isActor()`

  Is this an actor type?

- `core.Bool isPrimitive()`

  Is this a primitive type? e.g. int, float, etc. These do not need explicit construction and can be stored in registers. Note: Object-types and references are not primitives in this regard, as pointers generally need initialization. `void` is not considered a primitive.

- `core.Bool isAsmType()`

  Can this type be manipulated by the CPU directly. This includes the primitive types, but also reference types and object types. ASM types never have destructors. Does not consider references to be AsmTypes, as they are expected to be handled at a different level.

- `core.asm.TypeDesc desc(core.lang.Value v)`

  Get a description of this type.

- `core.asm.Operand copyCtor()`

  Get an Operand pointing to the copy constructor for this type. Only returns something useful for value types, as other types can and shall be copied using an inline mov-instruction.

- `core.asm.Operand destructor()`

  Get an Operand pointing to the destructor for this type. May return Operand(), meaning no destructor is needed.