[foreign] RFR 8219822: Jextract should handle complex macro constants

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Feb 27 23:19:52 UTC 2019


Hi,
here's a new revision where I just slightly improved the TestConstants 
test, to be more uniform (instead of passing expected constant values, 
the test now passes checker predicates, which is more scalable).

Webrev:

http://cr.openjdk.java.net/~mcimadamore/panama/8219822_v3/

Cheers
Maurizio


On 27/02/2019 19:02, Maurizio Cimadamore wrote:
> Hi,
> this patch regularizes support for constant macros (and enum constants 
> too).
>
> http://cr.openjdk.java.net/~mcimadamore/panama/8219822_v2/
>
> The goal of this patch is to stop having jextract generating 'default' 
> methods for constants. Instead, two new annotations are introduced:
>
> @NativeNumericConstant
> @NativeStringConstant
>
> The first takes a long value, the second a String value.
>
> So, given C code like this:
>
> #define FOO 1
>
> instead of generating a method like this:
>
> default int FOO() {
>    return 1;
> }
>
> We will now generate this:
>
> @NativeNumericConstant(1L)
> int FOO();
>
> And then binder will then generate the implementation.
>
> Decoupling the generation of the constant methods from jextract has a 
> big advantage: we can now support complex constant types, such as 
> strings (which need to be turned to Pointer<Byte>) and pointer 
> constants (e.g. (void*)0). Note that, whenever we need some 'constant' 
> pointer, we need to allocate, which means we need a scope - which we 
> don't have at extraction time.
>
> Efficiency-wise, the binder-generated implementation should be as good 
> as the jextract one - it just ldc a constant (which can even be a 
> pointer constant, via CP patching!) and then returns it.
>
> In order to support pointer constants of the kind:
>
> #define PTR (void*)0
>
> I also tweaked MacroParser, so that now two attempts can be made at 
> evaluating the macro:
>
> 1) a first attempt is made using a snippet like this:
>
> __auto_type jextract$var = PTR;
>
> If this fails (and it does fail in this case, as clang cursor 
> evaluation API doesn't detect this constant), then:
>
> 2) we look at the type of the cursor, if the type is a pointer type, 
> then we trigger another snippet parse, this time of:
>
> __auto_type jextract$var = (long)PTR;
>
> The extra cast will effectively reinterpret the value as a numeric 
> constant. Then we'll create a macro whose type is the pointer type 
> determined at (1) and whose value is the one determined at (2).
>
>
> Note that, since we only execute step (2) when the type of the cursor 
> in (1) is a pointer type, we don't end up executing the second step 
> very often. I also tried some of the examples, and the extraction time 
> is the same as before this patch.
>
>
> There is a slight issue with AsmCodeFactoryExt: ideally, we'd like for 
> constant methods to be turned into static constants here; and we'd 
> like to initialize such constants to the result of the computation of 
> the bound constant method - that is, if the library has a method:
>
> @NativeNumericConstant(1L)
> int FOO();
>
> Then, the static wrapper should have the following static field:
>
> static final int FOO = lib.FOO();
>
> However, if we do so, a test will fail, namely LibEnumTest, as that 
> test uses the constants of the static wrapper as labels in a 'switch' 
> statement; this only works if the constant field has the 
> 'ConstantValue' attribute, and that in turn is only possible if the 
> constant is 'simple' - using a condy-based ConstantValue would be a 
> way out, but that is not something that is supported currently, 
> neither by the VM nor by javac.
>
> So we have a choice here:
>
> 1) we extract the value of the constant, and we create a plain 
> constant field - e.g.
>
> static final int FOO = 1;
>
> which will then work as before (as a true compile-time constant)
>
> 2) we aim for regularity, and we just translate as
>
> static final int FOO = lib.FOO();
>
>
> The patch I've submitted does (1) for simple numeric constants and 
> falls back to (2) for complex constants. I'm open to suggestions as to 
> whether it's better to keep this behavior, or simplify it by always 
> aiming for (2).
>
> Maurizio
>
>
>
>


More information about the panama-dev mailing list