1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- package asm
- // Metadata contains metadata about an instruction.
- type Metadata struct {
- head *metaElement
- }
- type metaElement struct {
- next *metaElement
- key, value interface{}
- }
- // Find the element containing key.
- //
- // Returns nil if there is no such element.
- func (m *Metadata) find(key interface{}) *metaElement {
- for e := m.head; e != nil; e = e.next {
- if e.key == key {
- return e
- }
- }
- return nil
- }
- // Remove an element from the linked list.
- //
- // Copies as many elements of the list as necessary to remove r, but doesn't
- // perform a full copy.
- func (m *Metadata) remove(r *metaElement) {
- current := &m.head
- for e := m.head; e != nil; e = e.next {
- if e == r {
- // We've found the element we want to remove.
- *current = e.next
- // No need to copy the tail.
- return
- }
- // There is another element in front of the one we want to remove.
- // We have to copy it to be able to change metaElement.next.
- cpy := &metaElement{key: e.key, value: e.value}
- *current = cpy
- current = &cpy.next
- }
- }
- // Set a key to a value.
- //
- // If value is nil, the key is removed. Avoids modifying old metadata by
- // copying if necessary.
- func (m *Metadata) Set(key, value interface{}) {
- if e := m.find(key); e != nil {
- if e.value == value {
- // Key is present and the value is the same. Nothing to do.
- return
- }
- // Key is present with a different value. Create a copy of the list
- // which doesn't have the element in it.
- m.remove(e)
- }
- // m.head is now a linked list that doesn't contain key.
- if value == nil {
- return
- }
- m.head = &metaElement{key: key, value: value, next: m.head}
- }
- // Get the value of a key.
- //
- // Returns nil if no value with the given key is present.
- func (m *Metadata) Get(key interface{}) interface{} {
- if e := m.find(key); e != nil {
- return e.value
- }
- return nil
- }
|