001 package railo.transformer.bytecode.expression; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 006 import org.objectweb.asm.Type; 007 import org.objectweb.asm.commons.GeneratorAdapter; 008 import org.objectweb.asm.commons.Method; 009 010 import railo.transformer.bytecode.BytecodeContext; 011 import railo.transformer.bytecode.BytecodeException; 012 import railo.transformer.bytecode.expression.var.DataMember; 013 import railo.transformer.bytecode.expression.var.Member; 014 import railo.transformer.bytecode.expression.var.UDF; 015 import railo.transformer.bytecode.util.ExpressionUtil; 016 import railo.transformer.bytecode.util.Types; 017 018 public final class ExpressionInvoker extends ExpressionBase implements Invoker { 019 020 // Object getCollection (Object,String) 021 private final static Method GET_COLLECTION = new Method("getCollection", 022 Types.OBJECT, 023 new Type[]{Types.OBJECT,Types.STRING} 024 ); 025 026 // Object get (Object,String) 027 private final static Method GET = new Method("get", 028 Types.OBJECT, 029 new Type[]{Types.OBJECT,Types.STRING} 030 ); 031 032 // Object getFunction (Object,String,Object[]) 033 private final static Method GET_FUNCTION = new Method("getFunction", 034 Types.OBJECT, 035 new Type[]{Types.OBJECT,Types.STRING,Types.OBJECT_ARRAY} 036 ); 037 038 // Object getFunctionWithNamedValues (Object,String,Object[]) 039 private final static Method GET_FUNCTION_WITH_NAMED_ARGS = new Method("getFunctionWithNamedValues", 040 Types.OBJECT, 041 new Type[]{Types.OBJECT,Types.STRING,Types.OBJECT_ARRAY} 042 ); 043 044 045 private Expression expr; 046 private List members=new ArrayList(); 047 048 public ExpressionInvoker(Expression expr) { 049 super(expr.getLine()); 050 this.expr=expr; 051 } 052 053 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 054 055 GeneratorAdapter adapter = bc.getAdapter(); 056 057 Type rtn=Types.OBJECT; 058 int count=members.size(); 059 060 for(int i=0;i<count;i++) { 061 adapter.loadArg(0); 062 } 063 064 expr.writeOut(bc, Expression.MODE_REF); 065 066 for(int i=0;i<count;i++) { 067 Member member=((Member)members.get(i)); 068 069 // Data Member 070 if(member instanceof DataMember) { 071 ((DataMember)member).getName().writeOut(bc, MODE_REF); 072 adapter.invokeVirtual(Types.PAGE_CONTEXT,((i+1)==count)?GET:GET_COLLECTION); 073 rtn=Types.OBJECT; 074 } 075 076 // UDF 077 else if(member instanceof UDF) { 078 UDF udf=(UDF) member; 079 080 udf.getName().writeOut(bc, MODE_REF); 081 ExpressionUtil.writeOutExpressionArray(bc, Types.OBJECT, udf.getArguments()); 082 083 adapter.invokeVirtual(Types.PAGE_CONTEXT,udf.hasNamedArgs()?GET_FUNCTION_WITH_NAMED_ARGS:GET_FUNCTION); 084 rtn=Types.OBJECT; 085 086 } 087 } 088 089 return rtn; 090 } 091 092 /** 093 * 094 * @see railo.transformer.bytecode.expression.Invoker#addMember(railo.transformer.bytecode.expression.var.Member) 095 */ 096 public void addMember(Member member) { 097 members.add(member); 098 } 099 100 /** 101 * 102 * @see railo.transformer.bytecode.expression.Invoker#getMembers() 103 */ 104 public List getMembers() { 105 return members; 106 } 107 108 }