public void visitTernaryExpression(TernaryExpression expression) { onLineNumber(expression, "visitTernaryExpression"); controller.getBinaryExpressionHelper().evaluateTernary(expression); }
public void visitProperty(PropertyNode statement) { // the verifier created the field and the setter/getter methods, so here is // not really something to do onLineNumber(statement, "visitProperty:" + statement.getField().getName()); controller.setMethodNode(null); }
public void visitDeclarationExpression(DeclarationExpression expression) { onLineNumber(expression, "visitDeclarationExpression: \"" + expression.getText() + "\""); controller.getBinaryExpressionHelper().evaluateEqual(expression,true); }
public void writeAssert(AssertStatement statement) { controller.getAcg().onLineNumber(statement, "visitAssertStatement"); writeStatementLabel(statement); controller.getAssertionWriter().writeAssertStatement(statement); }
public void visitStaticMethodCallExpression(StaticMethodCallExpression call) { onLineNumber(call, "visitStaticMethodCallExpression: \"" + call.getMethod() + "\":"); controller.getInvocationWriter().writeInvokeStaticMethod(call); controller.getAssertionWriter().record(call); }
public void writeExpressionStatement(ExpressionStatement statement) { controller.getAcg().onLineNumber(statement, "visitExpressionStatement: " + statement.getExpression().getClass().getName()); writeStatementLabel(statement); Expression expression = statement.getExpression(); int mark = controller.getOperandStack().getStackLength(); expression.visit(controller.getAcg()); controller.getOperandStack().popDownTo(mark); } }
public void visitMethodCallExpression(MethodCallExpression call) { onLineNumber(call, "visitMethodCallExpression: \"" + call.getMethod() + "\":"); controller.getInvocationWriter().writeInvokeMethod(call); controller.getAssertionWriter().record(call.getMethod()); }
public void visitBinaryExpression(BinaryExpression expression) { onLineNumber(expression, "visitBinaryExpression: \"" + expression.getOperation().getText() + "\" "); controller.getBinaryExpressionHelper().eval(expression); controller.getAssertionWriter().record(expression.getOperation()); }
public void writeBreak(BreakStatement statement) { controller.getAcg().onLineNumber(statement, "visitBreakStatement"); writeStatementLabel(statement); String name = statement.getLabel(); Label breakLabel = controller.getCompileStack().getNamedBreakLabel(name); controller.getCompileStack().applyFinallyBlocks(breakLabel, true); controller.getMethodVisitor().visitJumpInsn(GOTO, breakLabel); }
public void visitConstructorCallExpression(ConstructorCallExpression call) { onLineNumber(call, "visitConstructorCallExpression: \"" + call.getType().getName() + "\":"); if (call.isSpecialCall()) { controller.getInvocationWriter().writeSpecialConstructorCall(call); return; } controller.getInvocationWriter().writeInvokeConstructor(call); controller.getAssertionWriter().record(call); }
public void writeThrow(ThrowStatement statement) { controller.getAcg().onLineNumber(statement, "visitThrowStatement"); writeStatementLabel(statement); MethodVisitor mv = controller.getMethodVisitor(); statement.getExpression().visit(controller.getAcg()); // we should infer the type of the exception from the expression mv.visitTypeInsn(CHECKCAST, "java/lang/Throwable"); mv.visitInsn(ATHROW); controller.getOperandStack().remove(1); }
public void writeSwitch(SwitchStatement statement) { controller.getAcg().onLineNumber(statement, "visitSwitch"); writeStatementLabel(statement); statement.getExpression().visit(controller.getAcg()); // switch does not have a continue label. use its parent's for continue Label breakLabel = controller.getCompileStack().pushSwitch(); final int switchVariableIndex = controller.getCompileStack().defineTemporaryVariable("switch", true); List caseStatements = statement.getCaseStatements(); int caseCount = caseStatements.size(); Label[] labels = new Label[caseCount + 1]; for (int i = 0; i < caseCount; i++) { labels[i] = new Label(); } int i = 0; for (Iterator iter = caseStatements.iterator(); iter.hasNext(); i++) { CaseStatement caseStatement = (CaseStatement) iter.next(); writeCaseStatement(caseStatement, switchVariableIndex, labels[i], labels[i + 1]); } statement.getDefaultStatement().visit(controller.getAcg()); controller.getMethodVisitor().visitLabel(breakLabel); controller.getCompileStack().removeVar(switchVariableIndex); controller.getCompileStack().pop(); }
public void writeContinue(ContinueStatement statement) { controller.getAcg().onLineNumber(statement, "visitContinueStatement"); writeStatementLabel(statement); String name = statement.getLabel(); Label continueLabel = controller.getCompileStack().getContinueLabel(); if (name != null) continueLabel = controller.getCompileStack().getNamedContinueLabel(name); controller.getCompileStack().applyFinallyBlocks(continueLabel, false); controller.getMethodVisitor().visitJumpInsn(GOTO, continueLabel); }
private FastPathData writeGuards(StatementMeta meta, Statement statement) { if (notEnableFastPath(meta)) return null; controller.getAcg().onLineNumber(statement, null); MethodVisitor mv = controller.getMethodVisitor(); FastPathData fastPathData = new FastPathData(); Label slowPath = new Label(); for (int i=0; i<guards.length; i++) { if (meta.involvedTypes[i]) { guards[i].call(mv); mv.visitJumpInsn(IFEQ, slowPath); } } // meta class check with boolean holder String owner = BytecodeHelper.getClassInternalName(controller.getClassNode()); MethodNode mn = controller.getMethodNode(); if (mn!=null) { mv.visitFieldInsn(GETSTATIC, owner, Verifier.STATIC_METACLASS_BOOL, "Z"); mv.visitJumpInsn(IFNE, slowPath); } //standard metaclass check disabledStandardMetaClass.call(mv); mv.visitJumpInsn(IFNE, slowPath); // other guards here mv.visitJumpInsn(GOTO, fastPathData.pathStart); mv.visitLabel(slowPath); return fastPathData; }
public void writeDoWhileLoop(DoWhileStatement loop) { controller.getAcg().onLineNumber(loop,"visitDoWhileLoop"); writeStatementLabel(loop); MethodVisitor mv = controller.getMethodVisitor(); controller.getCompileStack().pushLoop(loop.getStatementLabels()); Label breakLabel = controller.getCompileStack().getBreakLabel(); Label continueLabel = controller.getCompileStack().getContinueLabel(); mv.visitLabel(continueLabel); loop.getLoopBlock().visit(controller.getAcg()); loop.getBooleanExpression().visit(controller.getAcg()); controller.getOperandStack().jump(IFEQ, continueLabel); mv.visitLabel(breakLabel); controller.getCompileStack().pop(); }
protected void writeCaseStatement( CaseStatement statement, int switchVariableIndex, Label thisLabel, Label nextLabel) { controller.getAcg().onLineNumber(statement, "visitCaseStatement"); MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); mv.visitVarInsn(ALOAD, switchVariableIndex); statement.getExpression().visit(controller.getAcg()); operandStack.box(); controller.getBinaryExpressionHelper().getIsCaseMethod().call(mv); operandStack.replace(ClassHelper.boolean_TYPE); Label l0 = controller.getOperandStack().jump(IFEQ); mv.visitLabel(thisLabel); statement.getCode().visit(controller.getAcg()); // now if we don't finish with a break we need to jump past // the next comparison if (nextLabel != null) { mv.visitJumpInsn(GOTO, nextLabel); } mv.visitLabel(l0); }
@Override protected void writeForInLoop(final ForStatement loop) { controller.getAcg().onLineNumber(loop,"visitForLoop"); writeStatementLabel(loop); CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); compileStack.pushLoop(loop.getVariableScope(), loop.getStatementLabels()); // Identify type of collection TypeChooser typeChooser = controller.getTypeChooser(); Expression collectionExpression = loop.getCollectionExpression(); ClassNode collectionType = typeChooser.resolveType(collectionExpression, controller.getClassNode()); Parameter loopVariable = loop.getVariable(); int size = operandStack.getStackLength(); if (collectionType.isArray() && loopVariable.getOriginType().equals(collectionType.getComponentType())) { writeOptimizedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable); } else if (ENUMERATION_CLASSNODE.equals(collectionType)) { writeEnumerationBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable); } else { writeIteratorBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable); } operandStack.popDownTo(size); compileStack.pop(); }
public void writeIfElse(IfStatement ifElse) { controller.getAcg().onLineNumber(ifElse,"visitIfElse"); writeStatementLabel(ifElse); MethodVisitor mv = controller.getMethodVisitor(); ifElse.getBooleanExpression().visit(controller.getAcg()); Label l0 = controller.getOperandStack().jump(IFEQ); // if-else is here handled as a special version // of a boolean expression controller.getCompileStack().pushBooleanExpression(); ifElse.getIfBlock().visit(controller.getAcg()); controller.getCompileStack().pop(); if (ifElse.getElseBlock()==EmptyStatement.INSTANCE) { mv.visitLabel(l0); } else { Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); controller.getCompileStack().pushBooleanExpression(); ifElse.getElseBlock().visit(controller.getAcg()); controller.getCompileStack().pop(); mv.visitLabel(l1); } }
public void writeReturn(ReturnStatement statement) { controller.getAcg().onLineNumber(statement, "visitReturnStatement"); writeStatementLabel(statement); MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); ClassNode returnType = controller.getReturnType(); if (returnType == ClassHelper.VOID_TYPE) { if (!(statement.isReturningNullOrVoid())) { //TODO: move to Verifier controller.getAcg().throwException("Cannot use return statement with an expression on a method that returns void"); } controller.getCompileStack().applyBlockRecorder(); mv.visitInsn(RETURN); return; } Expression expression = statement.getExpression(); expression.visit(controller.getAcg()); operandStack.doGroovyCast(returnType); if (controller.getCompileStack().hasBlockRecorder()) { ClassNode type = operandStack.getTopOperand(); int returnValueIdx = controller.getCompileStack().defineTemporaryVariable("returnValue", returnType, true); controller.getCompileStack().applyBlockRecorder(); operandStack.load(type, returnValueIdx); controller.getCompileStack().removeVar(returnValueIdx); } BytecodeHelper.doReturn(mv, returnType); operandStack.remove(1); }
public void writeWhileLoop(WhileStatement loop) { controller.getAcg().onLineNumber(loop,"visitWhileLoop"); writeStatementLabel(loop); MethodVisitor mv = controller.getMethodVisitor(); controller.getCompileStack().pushLoop(loop.getStatementLabels()); Label continueLabel = controller.getCompileStack().getContinueLabel(); Label breakLabel = controller.getCompileStack().getBreakLabel(); mv.visitLabel(continueLabel); BooleanExpression bool = loop.getBooleanExpression(); boolean boolHandled = false; if (bool.getExpression() instanceof ConstantExpression) { ConstantExpression constant = (ConstantExpression) bool.getExpression(); if (constant.getValue()==Boolean.TRUE) { boolHandled = true; // do nothing } else if (constant.getValue()==Boolean.FALSE) { boolHandled = true; mv.visitJumpInsn(GOTO, breakLabel); } } if(!boolHandled) { bool.visit(controller.getAcg()); controller.getOperandStack().jump(IFEQ, breakLabel); } loop.getLoopBlock().visit(controller.getAcg()); mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); controller.getCompileStack().pop(); }