Avail Object
AvailObject is the fully realized, and mostly machine generated, implementation of an Avail object. An AvailObject must keep track of its descriptor, its integer data, and its references to other AvailObjects. It specifies the complete complement of messages that can be sent to an AvailObject, and delegates most of those to its descriptor, passing the AvailObject as an additional first argument. The redirected messages in AbstractDescriptor have the prefix "o_", both to make them stand out better and to indicate the additional first argument.
Author
Mark van Gulik
Todd L Smith
Parameters
This object's {@link AbstractDescriptor}.
The number of object slots to allocate.
The number of integer slots to allocate.
Types
Functions
Add a write reactor to the VariableDescriptor and associate it with the specified key (for subsequent removal).
Set up the object to report nice obvious errors if anyone ever accesses it again.
Extract the map from this variable, add the key → value binding to it, and write it back into the variable.
Extract the map from this variable, remove the key if present, and write it back into the variable.
Extract the current value of the indexable Long slot, pass it to the supplied inline Kotlin function, and write the result back to the slot with a compare-and-set, retrying from the beginning if it fails.
Extract the current value of the indexable object slot, pass it to the supplied Kotlin function, and write the result back to the slot with a compare-and-set, retrying from the beginning if it fails.
Turn the receiver into an indirection to the specified object.
Extract the byte at the given one-based byte subscript within the specified field. Always use little-endian encoding.
Sanity check: ensure that the specified field is writable.
Disconnect this token from its internal cache of what comes next.
Clear the variable. This causes the variable to have no value, and subsequent attempts to get the value of this variable will fail.
Answer the raw function (also known as compiled code) on which this function is based. The raw function holds the information that is common to all functions, and each function additionally holds zero or more captured variables and values from its lexical context.
Answer this raw function's Primitive or null.
Perform an atomic compare-and-set on a slot of the given array. If the value in the slot is the same Kotlin object (under ===) as the reference, replace it with the newValue and answer true. Otherwise answer false.
A convenience method that exposes the fact that a subtuple of a string is also a string.
Answer the method that this definition is for.
Answer the ModuleDescriptor in which this grammatical restriction was defined.
Utility method for decomposing this object in the debugger. See AvailObjectFieldHelper for instructions to enable this functionality in IntelliJ.
Retrieve this object's current descriptor.
Replace the descriptor with a filler. This blows up for most messages, catching further uses of this object. Note that all further uses are incorrect by definition.
Answer whether the receiver and the argument, both AvailObjects, are equal in value.
{@inheritDoc}
Answer whether the receiver, an AvailObject, and the argument, a tuple, are equal in value.
Answer whether the receiver, an AvailObject, and the argument, a byte string, are equal in value.
Answer whether the receiver, an AvailObject, and the argument, a byte tuple, are equal in value.
Answer whether the receiver, an AvailObject, and a compiled code, are equal.
Answer whether the receiver equals the argument.
Answer whether the receiver equals the argument.
Determine whether the receiver is an enumeration with the given set of instances.
Answer whether the receiver, an object, and the argument, a FiberTypeDescriptor, are equal in value.
Answer whether the receiver, an object, and the argument, a FunctionDescriptor, are equal in value.
Answer whether the receiver, an AvailObject, and the argument, a function type, are equal.
Answer whether the receiver, an AvailObject, and the argument, an integer interval, are equal in value.
Answer whether the receiver equals the argument.
Answer whether the receiver, an AvailObject, and the argument, an int tuple, are equal in value.
Answer whether this value equals the given ListPhraseTypeDescriptor.
Answer whether the receiver, an AvailObject, and the argument, a long tuple, are equal in value.
Answer whether the receiver equals the argument.
Dispatch to the descriptor.
Dispatch to the descriptor.
Dispatch to the descriptor.
Dispatch to the descriptor.
Answer whether the receiver, an AvailObject, and the argument, a repeated element tuple, are equal in value.
Answer whether the receiver and the argument tuple, both AvailObjects, are equal in value.
Dispatch to the descriptor.
Answer whether the receiver, an AvailObject, and the argument, a small integer interval tuple, are equal in value.
Dispatch to the descriptor.
Dispatch to the descriptor.
Answer whether the receiver equals the argument.
Given a continuation register dump, extract the Long at the given slot index.
Given a continuation register dump, extract the object at the given slot index.
Read the variable's value, add the addend to it, and store it back into the variable. This sequence of operations is protected by a lock if the variable is potentially shared among multiple Avail FiberDescriptor. Fail if the variable had no value, if the variable's content type is not a subtype of the IntegerRangeTypeDescriptor.extendedIntegers, if the addend is not an extended integer, if the sum of the old value and the addend is undefined (e.g., ∞ plus -∞), or if the sum does not satisfy the variable's VariableTypeDescriptor.o_WriteType. Return the previous value.
Extract a field from an ObjectDescriptor.
Extract a field from an ObjectDescriptor, using a one-based index into the field slots. This requires knowledge of the ObjectLayoutVariant, since the same field is at different indices in different variants.
Extract a field from an ObjectDescriptor, or answer null if it's not present.
Add or replace a field of an ObjectDescriptor.
Extract a field type from an ObjectTypeDescriptor.
Extract a field type from an ObjectTypeDescriptor, using the given field index, which is specific to an ObjectLayoutVariant.
Extract a field type from an ObjectTypeDescriptor, or null if it's not present.
Store the object in the specified slots of the receiver. The caller is responsible for ensuring the value has been marked Mutability.IMMUTABLE if necessary.
Answer the function to execute to determine the effect of this semantic restriction on a list of argument static types at a call site.
Answer the function type associated with this raw function's closures.
Read the variable's value and set it to the new value. Answer the old value. Fail if the new value is not suitable for the variable, or if the variable had no value. Ensure that the entire operation runs atomically with respect to other reads and writes of the variable. Use information about whether the variable is potentially shared between Avail FiberDescriptor to determine whether locking operations are needed.
Store the AvailObject in the specified slot of the receiver, and answer the value that was previously in that slot. Use atomic write semantics that are compatible with volatile access. Note that this may answer nil if it's used on an unassigned variable's value slot.
Extract the current value of the VariableDescriptor. Fail if the variable has no value.
Extract the current value of the VariableDescriptor. Fail if the variable has no value. Clear the variable afterward.
Read the current value of a variable without tripping any observerless mechanisms or checks. If the variable is unassigned, answer nil.
Only applicable to VariableSharedGlobalDescriptor. Answer the module in which it's defined.
Only applicable to VariableSharedGlobalDescriptor. Answer the name of this global variable or constant.
Redirect Kotlin's hashCode to AbstractDescriptor.o_Hash.
Dispatch to the descriptor.
Search for the key in the 32-bit Ints encoded within the longSlots that occur within those slots identified with the specified IntegerSlotsEnum. The int slots must be in ascending sorted order, and must be distinct. If the exact int is found, answer its zero-based index within this repeated slot (i.e., ≥0). If the exact int is not found, answer (-n-1), where n is the zero-based position of the leftmost element of the repeated slot which is greater than the key (if it was equal, the "if found" case would have applied).
Answer the number of Long slots.
Search for the key in the 32-bit Ints encoded within the longSlots that occur within those slots identified with the specified IntegerSlotsEnum. Only search the given range of indices. If the given Int value is found within the given range, answer the index of the intSlot. Otherwise answer zero (0).
Given a module in the process of being compiled, answer whether this token was constructed by the compiler from the module's source.
Dispatch to the descriptor.
Dispatch to the descriptor.
Answer whether this token is a LiteralTokenDescriptor, such as a string or number.
Answer an iterator suitable for traversing the elements of the receiver with a Java foreach construct.
The line number of this token in the source file.
Extract the literal value from this token. It must be a literal token.
Answer this token's string representation converted to lower case.
Dispatch to the descriptor.
The receiver is marked with an IMMUTABLE descriptor, but its subobjects have not yet been made immutable. Scan them now, and do any additional fix-ups necessary for the kind of object.
Dispatch to the descriptor.
The receiver is marked with a SHARED descriptor, but its subobjects have not yet been made shared. Scan them now, and do any additional fix-ups necessary for the kind of object.
Dispatch to the descriptor.
Dispatch to the descriptor.
Extract an integer (at most 32 bits) from the given BitField. If the receiver is shared, then acquire its monitor.
Extract the (signed 64-bit) integer for the given field enum value, using volatile-read semantics if the receiver is shared.
Extract the object at the specified slot of the receiver. If the receiver is shared, then acquire its monitor.
Extract the (signed 64-bit) integer at the given field enum value. If the receiver is shared, then use VolatileSlotHelper.volatileRead to acquire the value.
Extract the AvailObject at the specified slot of the receiver, using volatile-read semantics if the receiver is shared.
Answer a name suitable for labeling a field containing this object.
Answer the LexingState that follows this token, or null if it hasn't been set yet.
Answer the pojo AvailObject containing the ]LexingState that follows this token, or nil if it hasn't been set yet.
Answer the number of AvailObject slots.
Answer this function's lexically captured variable or constant value that has the specified index.
Set the specified captured variable/constant slot to the given variable or constant value.
Recursively print the receiver to the StringBuilder, unless it is already present in the recursion Map. Printing will begin at the specified indent level, measured in horizontal tab characters.
Remove the specified chunk from the receiver's set of dependent chunks.
Remove the write reactor associated with the specified AtomDescriptor from the VariableDescriptor.
Dispatch to the descriptor.
Answer the MessageBundleDescriptor that is restricted by this grammatical restriction.
Answer whether the objects occupy the same memory addresses.
Visit all of the object's object slots, passing the parent and child objects to the provided visitor.
Replace the byte at the given one-based byte subscript within the specified field. Always use little endian encoding.
Store the specified continuation in the receiver, which must be a fiber. This is the only circumstance in all of Avail in which a field of a (potentially) shared object may hold a non-shared object.
Given a module in the process of being compiled, alter this token to indicate that it was created directly from that module's source.
Replace this object's current currentDescriptorAbstractDescriptor].
Dispatch to the descriptor.
Store the (32-bit signed) Int at the given int-index of the receiver.
Store the signed 32-bit Int into the specified BitField, trimming upper bits beyond the BitField's size. If the receiver is shared, then use VolatileSlotHelper.compareAndSet to ensure only the intended bits are affected.
Store the (signed 64-bit) integer in the eight bytes starting at the given field enum value. If the receiver is Mutability.SHARED, then acquire its monitor.
Store the AvailObject in the specified slot of the receiver, using volatile-write semantics if the receiver is shared.
Store the (signed 64-bit) integer in the eight bytes starting at the given field enum value. If the receiver is shared, then use VolatileSlotHelper.volatileWrite to write the value.
Set this token's next LexingState.
Store the (16-bit unsigned) short at the given short-index of the receiver.
Replace the value of the BitField within this object.
Store the (signed 64-bit) integer in the eight bytes starting at the given field enum value.
Store the A_BasicObject in the specified object slot of the receiver.
Store the AvailObject in the specified slot of the receiver.
Read elements from consecutive slots of a LongArray, writing them to consecutive long slots of the receiver.
Read elements from consecutive slots of an array, writing them to consecutive slots of the receiver. It's the client's responsibility to ensure the values are suitably immutable or shared.
Write elements from the given List into consecutively numbered object slots. If the receiver is Mutability.SHARED, then the new value must also become shared (by the client) before it can be stored.
Read elements from consecutive integer slots of the sourceObject, writing them to consecutive slots of the receiver. It's the client's responsibility to ensure the values are suitably immutable or shared.
Read elements from consecutive slots of the sourceObject, writing them to consecutive slots of the receiver. It's the client's responsibility to ensure the values are suitably immutable or shared.
Read elements from consecutive slots of a tuple, writing them to consecutive slots of the receiver. It's the client's responsibility to ensure the values are suitably immutable or shared.
Replace my descriptor field with a FillerDescriptor. This blows up for most messages, catching incorrect (all, by definition) further accidental uses of this object.
Helper method for transferring this object's longSlots into an L1InstructionDecoder. The receiver's descriptor must be a CompiledCodeDescriptor.
Assign the given value to the VariableDescriptor. Fail if the value does not have a type suitable for the variable.
Assign the given value to the VariableDescriptor. The client should ensure that the value is acceptable for the variable.
Set whether this write-once variable was initialized from an expression which is stable – always produces the same value (modulo loading of modules) and has no side-effects.
Store the AvailObject in the specified slot of the receiver. Use volatile write semantics.
Extract a (16-bit unsigned) short at the given short-index of the receiver.
Answer whether to show value-specific content in the field name in the debugger.
Extract the value of the BitField of the receiver. Note that it's an Int even though the underlying longSlots array contains longs.
Extract the (signed 64-bit) integer for the given field enum value.
Extract the AvailObject from the specified object slot of the receiver.
Extract the (signed 64-bit) integer at the given field enum value.
Extract the AvailObject at the specified slot of the receiver.
Read consecutive long slots from the receiver, writing them into slots of a long array.
Create and answer a LexingState corresponding to the start of this token. It should not be used for subsequent parsing/lexing.
Answer the TokenDescriptor.TokenType of this token.
Follow indirections until a non-indirection is reached. Replace each indirection's target with the ultimate target.
Follow indirections until a non-indirection is reached. Replace each indirection's target with the ultimate target, even if it would cause the otherwise-forbidden immutable->mutable references. Only used during makeImmutable.
Follow indirections until a non-indirection is reached. Replace each indirection's target with the ultimate target, even if it would cause the otherwise-forbidden shared->unshared references. Only used during makeShared.
Reduce the number of long slots occupied by this object. In a raw memory model we would split the object representation into two objects, one at the original address, and a separate filler object occupying the long slots that were chopped off.
Slice the current AvailObject into two objects, the left one (at the same starting address as the input), and the right one (a filler object that nobody should ever create a pointer to). The new Filler can have zero post-header slots (i.e., just the header), but the left object must not, since it may turn into an indirection some day and will require at least one slot for the target pointer.
Extract the current Int value of the BitField, pass it to the supplied inline Kotlin function, and write the result back to the BitField. Note that this is not atomic, so other fields encoded in the same Long field may get clobbered if simultaneously updated by multiple threads.
Extract the current value of the Long slot, pass it to the supplied inline Kotlin function, and write the resulting Long back to the slot.
Extract the current value of the slot, pass it to the supplied inline Kotlin function, and write the result back to the slot.
Extract the current value of the slot, pass it to the supplied inline Kotlin function, make it shared, and write the result back to the slot.
Answer the set of write reactorFunctionDescriptor that have not previously activated.
Extract the current value of the VariableDescriptor. Answer nil if the variable has no value.
Answer whether this variable is both a write-once variable and initialized from an expression which is stable – always produces the same value (modulo loading of modules) and has no side-effects.
Answer the number of variable integer slots in this object. This does not include the fixed integer slots.
Test whether the map in this variable has the specified key.
Answer the number of variable object slots in this AvailObject. This does not include the fixed object slots.
Extract the AvailObject at the specified slot of the receiver. Use volatile semantics for the read.
Write an equivalent replacement object into an object field of this object. Since the replacement is semantically equivalent to the previous content, don't acquire a lock. Any necessary write barriers and other memory synchronizations are the responsibility of the caller.
Properties
Is the receiver an Avail byte string?
Is the receiver an Avail IntTupleDescriptor? This is conservative, in that some object tuples may only contain ints but not be reported as being int tuples.
Is the receiver an Avail LongTupleDescriptor? This is conservative, in that some object tuples may only contain longs but not be reported as being long tuples.
Is the receiver an Avail TwoByteStringDescriptor?