package me.august.lumen.compile.parser.ast.expr; import me.august.lumen.compile.codegen.BuildContext; import me.august.lumen.compile.parser.ast.Typed; import me.august.lumen.compile.resolve.type.UnresolvedType; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; public class RescueExpr extends Typed implements Expression { private Expression tryExpression; private Expression catchExpression; private int exceptionVariableIndex; public RescueExpr(UnresolvedType type, Expression tryExpression, Expression catchExpression) { super(type); this.tryExpression = tryExpression; this.catchExpression = catchExpression; } public int getExceptionVariableIndex() { return exceptionVariableIndex; } public void setExceptionVariableIndex(int exceptionVariableIndex) { this.exceptionVariableIndex = exceptionVariableIndex; } @Override public Expression[] getChildren() { return new Expression[]{tryExpression, catchExpression}; } @Override public Type expressionType() { return tryExpression.expressionType(); } // TODO fix codegen @Override public void generate(MethodVisitor visitor, BuildContext context) { Label start = new Label(); Label end = new Label(); Label handle = new Label(); visitor.visitTryCatchBlock(start, end, handle, getResolvedType().getInternalName()); visitor.visitLabel(start); tryExpression.generate(visitor, context); visitor.visitLabel(end); Label finish = new Label(); visitor.visitJumpInsn(Opcodes.GOTO, finish); visitor.visitLabel(handle); visitor.visitVarInsn(Opcodes.ASTORE, exceptionVariableIndex); catchExpression.generate(visitor, context); visitor.visitLabel(finish); } @Override public String toString() { return "RescueExpr{" + "tryExpression=" + tryExpression + ", catchExpression=" + catchExpression + '}'; } }