asmclassgenerator.java
来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 1,558 行 · 第 1/5 页
JAVA
1,558 行
}
public void visitBreakStatement(BreakStatement statement) {
onLineNumber(statement, "visitBreakStatement");
visitStatement(statement);
String name = statement.getLabel();
Label breakLabel = compileStack.getNamedBreakLabel(name);
compileStack.applyFinallyBlocks(breakLabel, true);
cv.visitJumpInsn(GOTO, breakLabel);
}
public void visitContinueStatement(ContinueStatement statement) {
onLineNumber(statement, "visitContinueStatement");
visitStatement(statement);
String name = statement.getLabel();
Label continueLabel = compileStack.getContinueLabel();
if (name!=null) continueLabel = compileStack.getNamedContinueLabel(name);
compileStack.applyFinallyBlocks(continueLabel, false);
cv.visitJumpInsn(GOTO, continueLabel);
}
public void visitSynchronizedStatement(SynchronizedStatement statement) {
onLineNumber(statement, "visitSynchronizedStatement");
visitStatement(statement);
statement.getExpression().visit(this);
final int index = compileStack.defineTemporaryVariable("synchronized", ClassHelper.Integer_TYPE,true);
final Label synchronizedStart = new Label();
final Label synchronizedEnd = new Label();
final Label catchAll = new Label();
cv.visitVarInsn(ALOAD, index);
cv.visitInsn(MONITORENTER);
cv.visitLabel(synchronizedStart);
Runnable finallyPart = new Runnable(){
public void run(){
cv.visitVarInsn(ALOAD, index);
cv.visitInsn(MONITOREXIT);
}
};
compileStack.pushFinallyBlock(finallyPart);
statement.getCode().visit(this);
finallyPart.run();
cv.visitJumpInsn(GOTO, synchronizedEnd);
cv.visitLabel(catchAll);
finallyPart.run();
cv.visitInsn(ATHROW);
cv.visitLabel(synchronizedEnd);
compileStack.popFinallyBlock();
exceptionBlocks.add(new Runnable() {
public void run() {
cv.visitTryCatchBlock(synchronizedStart, catchAll, catchAll, null);
}
});
}
public void visitThrowStatement(ThrowStatement statement) {
onLineNumber(statement, "visitThrowStatement");
visitStatement(statement);
statement.getExpression().visit(this);
// we should infer the type of the exception from the expression
cv.visitTypeInsn(CHECKCAST, "java/lang/Throwable");
cv.visitInsn(ATHROW);
}
public void visitReturnStatement(ReturnStatement statement) {
onLineNumber(statement, "visitReturnStatement");
visitStatement(statement);
ClassNode returnType = methodNode.getReturnType();
if (returnType==ClassHelper.VOID_TYPE) {
if (!(statement == ReturnStatement.RETURN_NULL_OR_VOID)) {
throwException("Cannot use return statement with an expression on a method that returns void");
}
compileStack.applyFinallyBlocks();
cv.visitInsn(RETURN);
outputReturn = true;
return;
}
Expression expression = statement.getExpression();
evaluateExpression(expression);
if (returnType==ClassHelper.OBJECT_TYPE && expression.getType() != null && expression.getType()==ClassHelper.VOID_TYPE) {
cv.visitInsn(ACONST_NULL); // cheat the caller
} else {
// return is based on class type
// we may need to cast
doConvertAndCast(returnType, expression, false, true, false);
helper.unbox(returnType);
}
if (compileStack.hasFinallyBlocks()) {
int returnValueIdx = compileStack.defineTemporaryVariable("returnValue",returnType,true);
compileStack.applyFinallyBlocks();
helper.load(returnType,returnValueIdx);
}
helper.doReturn(returnType);
outputReturn = true;
}
/**
* Casts to the given type unless it can be determined that the cast is unnecessary
*/
protected void doConvertAndCast(ClassNode type, Expression expression, boolean ignoreAutoboxing, boolean forceCast, boolean coerce) {
ClassNode expType = getExpressionType(expression);
// temp resolution: convert all primitive casting to corresponsing Object type
if (!ignoreAutoboxing && ClassHelper.isPrimitiveType(type)) {
type = ClassHelper.getWrapper(type);
}
if (forceCast || (type!=null && !type.equals(expType))) {
doConvertAndCast(type,coerce);
}
}
/**
* @param expression
*/
protected void evaluateExpression(Expression expression) {
visitAndAutoboxBoolean(expression);
Expression assignExpr = createReturnLHSExpression(expression);
if (assignExpr != null) {
leftHandExpression = false;
assignExpr.visit(this);
}
}
public void visitExpressionStatement(ExpressionStatement statement) {
onLineNumber(statement, "visitExpressionStatement: " + statement.getExpression().getClass().getName());
visitStatement(statement);
Expression expression = statement.getExpression();
visitAndAutoboxBoolean(expression);
if (isPopRequired(expression)) {
cv.visitInsn(POP);
}
}
// Expressions
//-------------------------------------------------------------------------
public void visitDeclarationExpression(DeclarationExpression expression) {
onLineNumber(expression, "visitDeclarationExpression: \""+expression.getVariableExpression().getName()+"\"");
Expression rightExpression = expression.getRightExpression();
// no need to visit left side, just get the variable name
VariableExpression vex = expression.getVariableExpression();
ClassNode type = vex.getType();
// lets not cast for primitive types as we handle these in field setting etc
if (ClassHelper.isPrimitiveType(type)) {
rightExpression.visit(this);
} else {
if (type!=ClassHelper.OBJECT_TYPE){
visitCastExpression(new CastExpression(type, rightExpression));
} else {
visitAndAutoboxBoolean(rightExpression);
}
}
compileStack.defineVariable(vex,true);
}
public void visitBinaryExpression(BinaryExpression expression) {
onLineNumber(expression, "visitBinaryExpression: \"" + expression.getOperation().getText() + "\" ");
switch (expression.getOperation().getType()) {
case Types.EQUAL : // = assignment
evaluateEqual(expression);
break;
case Types.COMPARE_IDENTICAL : // ===
evaluateBinaryExpression(compareIdenticalMethod, expression);
break;
case Types.COMPARE_EQUAL : // ==
evaluateBinaryExpression(compareEqualMethod, expression);
break;
case Types.COMPARE_NOT_EQUAL :
evaluateBinaryExpression(compareNotEqualMethod, expression);
break;
case Types.COMPARE_TO :
evaluateCompareTo(expression);
break;
case Types.COMPARE_GREATER_THAN :
evaluateBinaryExpression(compareGreaterThanMethod, expression);
break;
case Types.COMPARE_GREATER_THAN_EQUAL :
evaluateBinaryExpression(compareGreaterThanEqualMethod, expression);
break;
case Types.COMPARE_LESS_THAN :
evaluateBinaryExpression(compareLessThanMethod, expression);
break;
case Types.COMPARE_LESS_THAN_EQUAL :
evaluateBinaryExpression(compareLessThanEqualMethod, expression);
break;
case Types.LOGICAL_AND :
evaluateLogicalAndExpression(expression);
break;
case Types.LOGICAL_OR :
evaluateLogicalOrExpression(expression);
break;
case Types.BITWISE_AND :
evaluateBinaryExpression("and", expression);
break;
case Types.BITWISE_AND_EQUAL :
evaluateBinaryExpressionWithAsignment("and", expression);
break;
case Types.BITWISE_OR :
evaluateBinaryExpression("or", expression);
break;
case Types.BITWISE_OR_EQUAL :
evaluateBinaryExpressionWithAsignment("or", expression);
break;
case Types.BITWISE_XOR :
evaluateBinaryExpression("xor", expression);
break;
case Types.BITWISE_XOR_EQUAL :
evaluateBinaryExpressionWithAsignment("xor", expression);
break;
case Types.PLUS :
evaluateBinaryExpression("plus", expression);
break;
case Types.PLUS_EQUAL :
evaluateBinaryExpressionWithAsignment("plus", expression);
break;
case Types.MINUS :
evaluateBinaryExpression("minus", expression);
break;
case Types.MINUS_EQUAL :
evaluateBinaryExpressionWithAsignment("minus", expression);
break;
case Types.MULTIPLY :
evaluateBinaryExpression("multiply", expression);
break;
case Types.MULTIPLY_EQUAL :
evaluateBinaryExpressionWithAsignment("multiply", expression);
break;
case Types.DIVIDE :
evaluateBinaryExpression("div", expression);
break;
case Types.DIVIDE_EQUAL :
//SPG don't use divide since BigInteger implements directly
//and we want to dispatch through DefaultGroovyMethods to get a BigDecimal result
evaluateBinaryExpressionWithAsignment("div", expression);
break;
case Types.INTDIV :
evaluateBinaryExpression("intdiv", expression);
break;
case Types.INTDIV_EQUAL :
evaluateBinaryExpressionWithAsignment("intdiv", expression);
break;
case Types.MOD :
evaluateBinaryExpression("mod", expression);
break;
case Types.MOD_EQUAL :
evaluateBinaryExpressionWithAsignment("mod", expression);
break;
case Types.POWER :
evaluateBinaryExpression("power", expression);
break;
case Types.POWER_EQUAL :
evaluateBinaryExpressionWithAsignment("power", expression);
break;
case Types.LEFT_SHIFT :
evaluateBinaryExpression("leftShift", expression);
break;
case Types.LEFT_SHIFT_EQUAL :
evaluateBinaryExpressionWithAsignment("leftShift", expression);
break;
case Types.RIGHT_SHIFT :
evaluateBinaryExpression("rightShift", expression);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?