Actually, now that I think about it, there's an potentially better way. Simply have static analysis do the work for us:

class A
{
  int a;
  this new() {
    // if 'this = ...' is found before 'this.whatever' then
    // the automatic allocation is overriden. So we have no need
    // for any kind of @noalloc/@alloc() distinction.

    // More importantly, because allocation is type specific, we
    // strip this out when calling it from a derived class (see B)

    this = GC.alloc(A); // this stripped when called from B.new()
    this.a = ...;
  }
}

class B : A
{
  int b;
  this new() {
    super.new(); // use A.new() except for allocation
    this.b = ...;
  }
}


Basically what's happening is two functions are built out for each class constructor which defines a 'this = ...': one with the allocation stuff, and one without. When a derived class calls the super classes constructor, it's calling the one built without the allocation stuff.

There could also be some kind of cool tricks involved. For instance of you use 'typeof(this)' with 'GC.alloc()' (instead of 'A'), then it could keep the allocation stuff and the super.new() constructor and use the allocation logic, but still allocate the size appropriate for type 'B' when it's called:

class A
{
  this new() {
    if (condition) {
      this = GC.alloc(typeof(this));
    }
    else {
      this = malloc(typeof(this));
    }
    ...
  }
}

class B
{
  this new() {
    super.new(); // same allocation rules as A
    ...
  }
}

However, that last part's just a side thought, and I'm not sure if it would really work, or what the implementation costs would be.

Reply via email to