private void addEvaluateMethod(IRClass irClass) { // public abstract Object evaluate(IExternalSymbolMap symbols); IRSymbol symbolsParam = new IRSymbol(SYMBOLS_PARAM_NAME, getDescriptor(IExternalSymbolMap.class), false); _context.initBodyContext(false); _context.pushScope(true); _context.putSymbol(symbolsParam); List<IRStatement> statements = new ArrayList<IRStatement>(); IExpression expression = _fragment.getExpression(); if (expression instanceof IProgram) { Statement mainStatement = (Statement) ((IProgram) expression).getMainStatement(); statements.add(StatementTransformer.compile(_context, mainStatement)); // If the program doesn't terminate, then add in an explicit return null at the end. // This is likely in the case of a program that doesn't actually return a value boolean[] bAbsolute = {false}; ITerminalStatement terminalStmt = mainStatement.getLeastSignificantTerminalStatement(bAbsolute); if (!bAbsolute[0] || !(terminalStmt instanceof ReturnStatement) && !(terminalStmt instanceof ThrowStatement)) { statements.add(new IRReturnStatement(null, nullLiteral())); } } else if (expression.getType().equals(JavaTypes.pVOID())) { // If the expression has a void type, such as if it's a method call with no return value, then // compile // it as a synthetic statement and explicitly insert a return null statements.add(new IRSyntheticStatement(ExpressionTransformer.compile(expression, _context))); statements.add(new IRReturnStatement(null, nullLiteral())); } else { // If the expression has a value, just return that (after boxing it, if necessary) IRExpression returnValue = ExpressionTransformer.compile(expression, _context); if (returnValue.getType().isPrimitive()) { returnValue = boxValue(returnValue.getType(), returnValue); } statements.add(new IRReturnStatement(null, returnValue)); } IRMethodStatement methodStatement = new IRMethodStatement( new IRStatementList(true, statements), "evaluate", Opcodes.ACC_PUBLIC, IRTypeConstants.OBJECT(), Collections.singletonList(symbolsParam)); irClass.addMethod(methodStatement); }
private void addEvaluateRootMethod(IRClass irClass) { // Only bother adding in the method if the fragment's root is an IMemberAccessExpression; // otherwise the method // is already implemented to return null on FragmentInstance IExpression expr = maybeUnwrap(_fragment.getExpression()); if (expr instanceof IMemberAccessExpression) { // public abstract Object evaluateRootExpression(IExternalSymbolMap symbols); IRSymbol symbolsParam = new IRSymbol(SYMBOLS_PARAM_NAME, getDescriptor(IExternalSymbolMap.class), false); _context.initBodyContext(false); _context.pushScope(true); _context.putSymbol(symbolsParam); List<IRStatement> statements = new ArrayList<IRStatement>(); IRExpression returnValue = ExpressionTransformer.compile( ((IMemberAccessExpression) expr).getRootExpression(), _context); if (returnValue.getType().isPrimitive()) { returnValue = boxValue(returnValue.getType(), returnValue); } statements.add(new IRReturnStatement(null, returnValue)); IRMethodStatement methodStatement = new IRMethodStatement( new IRStatementList(true, statements), "evaluateRootExpression", Opcodes.ACC_PUBLIC, IRTypeConstants.OBJECT(), Collections.singletonList(symbolsParam)); irClass.addMethod(methodStatement); } }