Simn / genjvm

13 stars 1 forks source link

Reflection #6

Closed Simn closed 5 years ago

Simn commented 5 years ago

It has to be done eventually. This requires generating some auxiliary type information in a way that it doesn't bother the run-time too much. I don't really want to think about this though.

Simn commented 5 years ago

I added support for annotations and use them to support enum name lookups:

package haxe.macro;

import haxe.jvm.Enum;
import haxe.jvm.annotation.EnumReflectionInformation;

@EnumReflectionInformation(constructorNames={"EConst", "EArray", "EBinop", "EField", "EParenthesis", "EObjectDecl", "EArrayDecl", "ECall", "ENew", "EUnop", "EVars", "EFunction", "EBlock", "EFor", "EIf", "EWhile", "ESwitch", "ETry", "EReturn", "EBreak", "EContinue", "EUntyped", "EThrow", "ECast", "EDisplay", "EDisplayNew", "ETernary", "ECheckType", "EMeta"})
public class ExprDef
  extends Enum
{
  public ExprDef(int paramInt, Object[] paramArrayOfObject)
  {
    super(paramInt, paramArrayOfObject);
  }
}

I think this is the best approach. I would like to use annotations for other reflection information as well because it keeps the data much cleaner.

nadako commented 5 years ago

Great idea! I think we should probably use enum-as-classes for java though :)

Simn commented 5 years ago

What do you mean?

nadako commented 5 years ago

Something similar to what I once did for C#: https://github.com/HaxeFoundation/haxe/pull/6119

The idea is to have an abstract class for the enum type and a subclass for each of the constructors, having the constructor arguments nicely packed into fields, so only one downcast is needed to access the inner structure.

basically:

enum E {
 A;
 B(v:Int);
}

into

abstract class E {

 // inner classes are nice for this i guess
 class A extends E {}

 class B extends E {
  final int v;
  public B(int v) {
    this.v = v;
  }
 }

 static final A = new A(); // not sure about how to better avoid name clashes here

 static E B(int v) { return new B(v); }
}

then on pattern matching we downcast the object to specific class and simply access its fields. ideally we should tempvar the downcast too (currently not done in the C# version)

Simn commented 5 years ago

I wonder if that's worth it performance-wise. I imagine that a lookup + cast on Object[] gets optimized like crazy by the JIT, especially if the array can be determined to be immutable (not sure if we can hint at that somehow).

But I certainly don't mind trying.

nadako commented 5 years ago

Well, let's think about this later :) Tho it's not only about reading, but also construction, because here you'd have to allocate an array and box the values, which might be expensive and I'm not sure it's easily optimizable by the JIT.

Simn commented 5 years ago

Turns out my enum implementation doesn't actually work, so we should go for nadako-enums.

Simn commented 5 years ago

We have nadako-enums now.

I'll close this issue and keep track of missing API in #21. I'll also open another one for Reflect.hx.