Skip to content

Commit 3da1ede

Browse files
committed
Add ability to use byte in GenerateEnumConstants
1 parent 6012d32 commit 3da1ede

File tree

6 files changed

+71
-56
lines changed

6 files changed

+71
-56
lines changed

graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/GenerateEnumConstants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,10 @@
4545

4646
@Target(ElementType.TYPE)
4747
public @interface GenerateEnumConstants {
48+
enum Type {
49+
INT,
50+
BYTE
51+
}
52+
53+
Type type() default Type.INT;
4854
}

graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/GenerateEnumConstantsProcessor.java

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import javax.tools.Diagnostic.Kind;
5757
import javax.tools.JavaFileObject;
5858

59+
import com.oracle.graal.python.annotations.GenerateEnumConstants;
5960
import com.oracle.graal.python.processor.CodeWriter.Block;
6061

6162
@SupportedAnnotationTypes("com.oracle.graal.python.annotations.GenerateEnumConstants")
@@ -67,59 +68,68 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
6768
if (re.processingOver()) {
6869
return false;
6970
}
70-
for (TypeElement annotation : annotations) {
71-
Set<? extends Element> annotatedElements = re.getElementsAnnotatedWith(annotation);
72-
for (Element el : annotatedElements) {
73-
if (el.getKind() == ElementKind.ENUM) {
74-
try {
75-
Element enc = el.getEnclosingElement();
76-
int enclosingTypes = 0;
77-
OUTER: while (enc != null) {
78-
switch (enc.getKind()) {
79-
case CLASS:
80-
case ENUM:
81-
case INTERFACE:
82-
enclosingTypes++;
83-
break;
84-
default:
85-
break OUTER;
86-
}
87-
enc.getEnclosingElement();
71+
Set<? extends Element> annotatedElements = re.getElementsAnnotatedWith(GenerateEnumConstants.class);
72+
for (Element el : annotatedElements) {
73+
GenerateEnumConstants annotation = el.getAnnotation(GenerateEnumConstants.class);
74+
boolean useByte = annotation.type() == GenerateEnumConstants.Type.BYTE;
75+
String elementType = useByte ? "byte" : "int";
76+
if (el.getKind() == ElementKind.ENUM) {
77+
try {
78+
Element enc = el.getEnclosingElement();
79+
int enclosingTypes = 0;
80+
OUTER: while (enc != null) {
81+
switch (enc.getKind()) {
82+
case CLASS:
83+
case ENUM:
84+
case INTERFACE:
85+
enclosingTypes++;
86+
break;
87+
default:
88+
break OUTER;
8889
}
89-
String qualName = ((TypeElement) el).getQualifiedName() + "Constants";
90-
String pkgName = qualName.substring(0, qualName.lastIndexOf('.'));
91-
String className = qualName.substring(qualName.lastIndexOf('.') + 1);
90+
enc.getEnclosingElement();
91+
}
92+
String qualName = ((TypeElement) el).getQualifiedName() + "Constants";
93+
String pkgName = qualName.substring(0, qualName.lastIndexOf('.'));
94+
String className = qualName.substring(qualName.lastIndexOf('.') + 1);
9295

93-
while (enclosingTypes-- > 0) {
94-
className = pkgName.substring(qualName.lastIndexOf('.') + 1) + className;
95-
pkgName = pkgName.substring(0, pkgName.lastIndexOf('.'));
96-
qualName = pkgName + "." + className;
97-
}
96+
while (enclosingTypes-- > 0) {
97+
className = pkgName.substring(qualName.lastIndexOf('.') + 1) + className;
98+
pkgName = pkgName.substring(0, pkgName.lastIndexOf('.'));
99+
qualName = pkgName + "." + className;
100+
}
98101

99-
JavaFileObject file = processingEnv.getFiler().createSourceFile(qualName);
100-
try (CodeWriter w = new CodeWriter(file.openWriter())) {
101-
w.writeLn("// CheckStyle: start generated");
102-
w.writeLn("// Auto generated by GenerateEnumConstantsProcessor at %s", LocalDateTime.now());
103-
w.writeLn("package %s;", pkgName);
104-
w.writeLn();
105-
w.writeLn("public final class %s {", className);
106-
int i = 0;
107-
for (Element enumBit : el.getEnclosedElements()) {
108-
if (enumBit.getKind() == ElementKind.ENUM_CONSTANT) {
109-
String enumName = ((VariableElement) enumBit).getSimpleName().toString();
110-
try (Block b = w.newIndent()) {
111-
w.writeLn("public static final int %s = %d;", enumName, i++);
102+
JavaFileObject file = processingEnv.getFiler().createSourceFile(qualName);
103+
try (CodeWriter w = new CodeWriter(file.openWriter())) {
104+
w.writeLn("// CheckStyle: start generated");
105+
w.writeLn("// Auto generated by GenerateEnumConstantsProcessor at %s", LocalDateTime.now());
106+
w.writeLn("package %s;", pkgName);
107+
w.writeLn();
108+
w.writeLn("public final class %s {", className);
109+
int i = 0;
110+
for (Element enumBit : el.getEnclosedElements()) {
111+
if (enumBit.getKind() == ElementKind.ENUM_CONSTANT) {
112+
String enumName = ((VariableElement) enumBit).getSimpleName().toString();
113+
try (Block b = w.newIndent()) {
114+
int value = i++;
115+
if (useByte) {
116+
if (value <= 0xFF) {
117+
value = (byte) value;
118+
} else {
119+
throw new IllegalArgumentException("Enum constant doesn't fit into byte");
120+
}
112121
}
122+
w.writeLn("public static final %s %s = %d;", elementType, enumName, value);
113123
}
114124
}
115-
w.writeLn("}");
116125
}
117-
} catch (IOException e) {
118-
processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), el);
126+
w.writeLn("}");
119127
}
120-
} else {
121-
processingEnv.getMessager().printMessage(Kind.ERROR, "Can only annotate enums with @GenerateEnumConstants", el);
128+
} catch (IOException e) {
129+
processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), el);
122130
}
131+
} else {
132+
processingEnv.getMessager().printMessage(Kind.ERROR, "Can only annotate enums with @GenerateEnumConstants", el);
123133
}
124134
}
125135
return true;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ private static Object[] extractConstants(RootNode node) {
330330
CodeUnit co = ((PBytecodeRootNode) rootNode).getCodeUnit();
331331
Set<Object> bytecodeConstants = new HashSet<>();
332332
for (int bci = 0; bci < co.code.length;) {
333-
OpCodes op = OpCodes.VALUES[co.code[bci]];
333+
OpCodes op = OpCodes.fromOpCode(co.code[bci]);
334334
if (op.quickens != null) {
335335
op = op.quickens;
336336
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CodeUnit.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,6 @@ public CodeUnit(TruffleString name, TruffleString qualname,
143143
this.generalizeVarsMap = generalizeVarsMap;
144144
}
145145

146-
OpCodes codeForBC(int bc) {
147-
return OpCodes.VALUES[bc];
148-
}
149-
150146
public int bciToSrcOffset(int bci) {
151147
int diffIdx = 0;
152148
int currentOffset = startOffset;
@@ -156,7 +152,7 @@ public int bciToSrcOffset(int bci) {
156152
if (bci <= i) {
157153
break;
158154
} else {
159-
OpCodes op = codeForBC(code[i]);
155+
OpCodes op = OpCodes.fromOpCode(code[i]);
160156
i += op.length();
161157
bytecodeNumber++;
162158
}
@@ -248,8 +244,7 @@ public String toString(byte[] bytecode) {
248244
int oparg = 0;
249245
while (bci < bytecode.length) {
250246
int bcBCI = bci;
251-
int bc = Byte.toUnsignedInt(bytecode[bci++]);
252-
OpCodes opcode = codeForBC(bc);
247+
OpCodes opcode = OpCodes.fromOpCode(bytecode[bci++]);
253248

254249
String[] line = lines.computeIfAbsent(bcBCI, k -> new String[DISASSEMBLY_NUM_COLUMNS]);
255250

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/OpCodes.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
* opcodes can have multiple bytes of immediate operands. The first operand can be variably extended
5353
* using {@link #EXTENDED_ARG} instruction.
5454
*/
55-
@GenerateEnumConstants
55+
@GenerateEnumConstants(type = GenerateEnumConstants.Type.BYTE)
5656
public enum OpCodes {
5757
/** Pop a single item from the stack */
5858
POP_TOP(0, 1, 0),
@@ -737,7 +737,11 @@ public static final class MakeFunctionFlags {
737737
public static final int HAS_CLOSURE = 0x08;
738738
}
739739

740-
public static final OpCodes[] VALUES = new OpCodes[values().length];
740+
private static final OpCodes[] VALUES = new OpCodes[values().length];
741+
742+
public static OpCodes fromOpCode(byte opcode) {
743+
return VALUES[Byte.toUnsignedInt(opcode)];
744+
}
741745

742746
static {
743747
assert values().length < 256;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,7 +1915,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
19151915
}
19161916
default:
19171917
CompilerDirectives.transferToInterpreterAndInvalidate();
1918-
throw PRaiseNode.raiseUncached(this, SystemError, toTruffleStringUncached("not implemented bytecode %s"), OpCodes.VALUES[bc]);
1918+
throw PRaiseNode.raiseUncached(this, SystemError, toTruffleStringUncached("not implemented bytecode %s"), OpCodes.fromOpCode(bc));
19191919
}
19201920
// prepare next loop
19211921
oparg = 0;
@@ -2835,7 +2835,7 @@ private void generalizeInputs(int beginBci) {
28352835
if (generalizeInputsMap[beginBci] != null) {
28362836
for (int i = 0; i < generalizeInputsMap[beginBci].length; i++) {
28372837
int generalizeBci = generalizeInputsMap[beginBci][i];
2838-
OpCodes generalizeInstr = OpCodes.VALUES[bytecode[generalizeBci]];
2838+
OpCodes generalizeInstr = OpCodes.fromOpCode(bytecode[generalizeBci]);
28392839
if (generalizeInstr.generalizesTo != null) {
28402840
bytecode[generalizeBci] = (byte) generalizeInstr.generalizesTo.ordinal();
28412841
}

0 commit comments

Comments
 (0)