Skip to content

References to other objects / local variable pointers #206

@nebkat

Description

@nebkat

I'm working with a format that has internal references to other objects based on their object IDs:

// Simplified
using ObjectId = u8;
using ReferencedObjectId = u8;
struct Object {
    ObjectId id;
    ReferencedObjectId referencedObjectId;
};

Object objects[while($ < std::mem::size())] @ 0x0;
01 04 // Object 1 => 4
04 03 // Object 4 => 3
03 01 // Object 3 => 1

I would like to have referencedObjectId be a link/reference to the appropriate object in the array, if found.


As a partial solution I have been able to hack together a way for the objects to have a pointer to other objects by doing the following:

g_objects[256];
fn get_object_ptr(u8 ptr) {
    return g_objects[ptr] - ptr; // Subtract ptr because it is about to be added to the base
}

using ObjectId = u8;
struct ReferencedObjectId {
    ObjectId id [[no_unique_address]];
    ObjectId *ptr : u16 [[pointer_base("get_object_ptr"), inline]];
};

struct Object {
    g_objects[std::mem::read_unsigned($, 1)] = $;
    ObjectId id;
    ReferencedObjectId referencedObjectId;
};

// First pass to build map
Object objectsFirstPass[while($ < std::mem::size())] @ 0x0 [[hidden]];

// Second pass
Object objects[while($ < std::mem::size())] @ 0x0;

The end result in terms of the pattern data is actually perfect but as you can see it's quite a horrible way to go about it.


Some possible solutions/improvements I have identified:

  1. Allow local variable pointers: ObjectId *ptr : u16 = g_addresses[id];
  2. Allow [[transform]] on pointers or [[pointer_transform]] in place of [[pointer_base]]
  3. A reference data type (to map to other objects in the pattern data view)
  4. A map data type (to avoid the large array)
  5. A "lazy" mechanism that would evaluate a local variable after the initial pass, so that the objects array could be available for searching.

A combination of 3/4/5 (rather ambitious!) would allow:

struct ReferencedObjectId {
    ObjectId id;
    lazy Object reference = objects[id];
}

Is there some alternative way this can be achieved?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions