Hi, I just found when doing pattern matching on Scala 3’ enum, the bytecode is not a tableswitch
when it’s possible:
Where the enum is just a tag object.
enum CompOp {
/** `==` */
case Eq
/** `!=` */
case Neq
//...
}
and user side:
private def evalCompare(compOp: CompOp, lhs: Expr, rhs: Expr, env: Environment): Value = {
val left = eval(lhs, env)
val right = eval(rhs, env)
compOp match
case CompOp.Eq => VBool(left.eq(right))
case CompOp.Neq => VBool(!left.eq(right))
case CompOp.Lt => left < right
case CompOp.Lte => left <= right
case CompOp.Gt => left > right
case CompOp.Gte => left >= right
case CompOp.In => VBool(left.isIn(right))
}
and the bytecode:
// access flags 0x2
private evalCompare(Lcom/taobao/amdc2/condition/optimizer/CompOp;Lcom/taobao/amdc2/condition/optimizer/Expr;Lcom/taobao/amdc2/condition/optimizer/Expr;Lcom/taobao/amdc2/condition/optimizer/eval/Environment;)Lcom/taobao/amdc2/condition/optimizer/eval/Value;
// parameter final compOp
// parameter final lhs
// parameter final rhs
// parameter final env
L0
LINENUMBER 56 L0
ALOAD 0
ALOAD 2
ALOAD 4
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/ExprEvaluator.eval (Lcom/taobao/amdc2/condition/optimizer/Expr;Lcom/taobao/amdc2/condition/optimizer/eval/Environment;)Lcom/taobao/amdc2/condition/optimizer/eval/Value;
ASTORE 5
L1
LINENUMBER 57 L1
ALOAD 0
ALOAD 3
ALOAD 4
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/ExprEvaluator.eval (Lcom/taobao/amdc2/condition/optimizer/Expr;Lcom/taobao/amdc2/condition/optimizer/eval/Environment;)Lcom/taobao/amdc2/condition/optimizer/eval/Value;
ASTORE 6
L2
LINENUMBER 59 L2
ALOAD 1
ASTORE 7
L3
LINENUMBER 60 L3
GETSTATIC com/taobao/amdc2/condition/optimizer/CompOp$.Eq : Lcom/taobao/amdc2/condition/optimizer/CompOp;
ALOAD 7
ASTORE 8
DUP
IFNONNULL L4
POP
ALOAD 8
IFNULL L5
GOTO L6
L4
FRAME FULL [com/taobao/amdc2/condition/optimizer/ExprEvaluator com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/eval/Environment com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp] [com/taobao/amdc2/condition/optimizer/CompOp]
ALOAD 8
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
IFEQ L6
L5
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/eval/Value$VBool$.MODULE$ : Lcom/taobao/amdc2/condition/optimizer/eval/Value$VBool$;
ALOAD 5
ALOAD 6
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value.eq (Lcom/taobao/amdc2/condition/optimizer/eval/Value;)Z
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value$VBool$.apply (Z)Lcom/taobao/amdc2/condition/optimizer/eval/Value$VBool;
ARETURN
L6
LINENUMBER 61 L6
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/CompOp$.Neq : Lcom/taobao/amdc2/condition/optimizer/CompOp;
ALOAD 7
ASTORE 9
DUP
IFNONNULL L7
POP
ALOAD 9
IFNULL L8
GOTO L9
L7
FRAME FULL [com/taobao/amdc2/condition/optimizer/ExprEvaluator com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/eval/Environment com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp] [com/taobao/amdc2/condition/optimizer/CompOp]
ALOAD 9
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
IFEQ L9
L8
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/eval/Value$VBool$.MODULE$ : Lcom/taobao/amdc2/condition/optimizer/eval/Value$VBool$;
ALOAD 5
ALOAD 6
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value.eq (Lcom/taobao/amdc2/condition/optimizer/eval/Value;)Z
IFNE L10
ICONST_1
GOTO L11
L10
FRAME SAME1 com/taobao/amdc2/condition/optimizer/eval/Value$VBool$
ICONST_0
L11
FRAME FULL [com/taobao/amdc2/condition/optimizer/ExprEvaluator com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/eval/Environment com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp] [com/taobao/amdc2/condition/optimizer/eval/Value$VBool$ I]
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value$VBool$.apply (Z)Lcom/taobao/amdc2/condition/optimizer/eval/Value$VBool;
ARETURN
L9
LINENUMBER 62 L9
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/CompOp$.Lt : Lcom/taobao/amdc2/condition/optimizer/CompOp;
ALOAD 7
ASTORE 10
DUP
IFNONNULL L12
POP
ALOAD 10
IFNULL L13
GOTO L14
L12
FRAME FULL [com/taobao/amdc2/condition/optimizer/ExprEvaluator com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/eval/Environment com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp] [com/taobao/amdc2/condition/optimizer/CompOp]
ALOAD 10
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
IFEQ L14
L13
FRAME SAME
ALOAD 5
ALOAD 6
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value.Lt (Lcom/taobao/amdc2/condition/optimizer/eval/Value;)Lcom/taobao/amdc2/condition/optimizer/eval/Value;
ARETURN
L14
LINENUMBER 63 L14
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/CompOp$.Lte : Lcom/taobao/amdc2/condition/optimizer/CompOp;
ALOAD 7
ASTORE 11
DUP
IFNONNULL L15
POP
ALOAD 11
IFNULL L16
GOTO L17
L15
FRAME FULL [com/taobao/amdc2/condition/optimizer/ExprEvaluator com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/eval/Environment com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp] [com/taobao/amdc2/condition/optimizer/CompOp]
ALOAD 11
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
IFEQ L17
L16
FRAME SAME
ALOAD 5
ALOAD 6
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value.Lte (Lcom/taobao/amdc2/condition/optimizer/eval/Value;)Lcom/taobao/amdc2/condition/optimizer/eval/Value;
ARETURN
L17
LINENUMBER 64 L17
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/CompOp$.Gt : Lcom/taobao/amdc2/condition/optimizer/CompOp;
ALOAD 7
ASTORE 12
DUP
IFNONNULL L18
POP
ALOAD 12
IFNULL L19
GOTO L20
L18
FRAME FULL [com/taobao/amdc2/condition/optimizer/ExprEvaluator com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/eval/Environment com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp] [com/taobao/amdc2/condition/optimizer/CompOp]
ALOAD 12
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
IFEQ L20
L19
FRAME SAME
ALOAD 5
ALOAD 6
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value.Gt (Lcom/taobao/amdc2/condition/optimizer/eval/Value;)Lcom/taobao/amdc2/condition/optimizer/eval/Value;
ARETURN
L20
LINENUMBER 65 L20
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/CompOp$.Gte : Lcom/taobao/amdc2/condition/optimizer/CompOp;
ALOAD 7
ASTORE 13
DUP
IFNONNULL L21
POP
ALOAD 13
IFNULL L22
GOTO L23
L21
FRAME FULL [com/taobao/amdc2/condition/optimizer/ExprEvaluator com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/eval/Environment com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp] [com/taobao/amdc2/condition/optimizer/CompOp]
ALOAD 13
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
IFEQ L23
L22
FRAME SAME
ALOAD 5
ALOAD 6
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value.Gte (Lcom/taobao/amdc2/condition/optimizer/eval/Value;)Lcom/taobao/amdc2/condition/optimizer/eval/Value;
ARETURN
L23
LINENUMBER 66 L23
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/CompOp$.In : Lcom/taobao/amdc2/condition/optimizer/CompOp;
ALOAD 7
ASTORE 14
DUP
IFNONNULL L24
POP
ALOAD 14
IFNULL L25
GOTO L26
L24
FRAME FULL [com/taobao/amdc2/condition/optimizer/ExprEvaluator com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/Expr com/taobao/amdc2/condition/optimizer/eval/Environment com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/eval/Value com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp com/taobao/amdc2/condition/optimizer/CompOp] [com/taobao/amdc2/condition/optimizer/CompOp]
ALOAD 14
INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
IFEQ L26
L25
FRAME SAME
GETSTATIC com/taobao/amdc2/condition/optimizer/eval/Value$VBool$.MODULE$ : Lcom/taobao/amdc2/condition/optimizer/eval/Value$VBool$;
ALOAD 5
ALOAD 6
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value.isIn (Lcom/taobao/amdc2/condition/optimizer/eval/Value;)Z
INVOKEVIRTUAL com/taobao/amdc2/condition/optimizer/eval/Value$VBool$.apply (Z)Lcom/taobao/amdc2/condition/optimizer/eval/Value$VBool;
ARETURN
L26
FRAME SAME
NEW scala/MatchError
DUP
ALOAD 7
INVOKESPECIAL scala/MatchError.<init> (Ljava/lang/Object;)V
ATHROW
L27
LOCALVARIABLE left Lcom/taobao/amdc2/condition/optimizer/eval/Value; L1 L27 5
LOCALVARIABLE right Lcom/taobao/amdc2/condition/optimizer/eval/Value; L2 L27 6
LOCALVARIABLE this Lcom/taobao/amdc2/condition/optimizer/ExprEvaluator; L0 L27 0
LOCALVARIABLE compOp Lcom/taobao/amdc2/condition/optimizer/CompOp; L0 L27 1
LOCALVARIABLE lhs Lcom/taobao/amdc2/condition/optimizer/Expr; L0 L27 2
LOCALVARIABLE rhs Lcom/taobao/amdc2/condition/optimizer/Expr; L0 L27 3
LOCALVARIABLE env Lcom/taobao/amdc2/condition/optimizer/eval/Environment; L0 L27 4
MAXSTACK = 3
MAXLOCALS = 15