Search in sources :

Example 6 with Member

use of lucee.transformer.expression.var.Member in project Lucee by lucee.

the class OPUnary method _writeOut.

@Override
public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException {
    GeneratorAdapter adapter = bc.getAdapter();
    // convert value
    if (operation == CONCAT)
        value = CastString.toExprString(value);
    else
        value = CastDouble.toExprDouble(value);
    List<Member> members = var.getMembers();
    int size = members.size();
    String scope = VariableInterpreter.scopeInt2String(var.getScope());
    /*
		 *  (susi.sorglos++ or variables.susi++)
		 */
    if ((scope == null && size > 1) || (scope != null && size > 0)) {
        Member last = var.removeMember(members.size() - 1);
        if (!(last instanceof DataMember))
            throw new TransformerException("you cannot use a unary operator with a function " + last.getClass().getName(), getStart());
        // write the variable
        var.setAsCollection(Boolean.TRUE);
        var.writeOut(bc, mode);
        // write out last Key
        getFactory().registerKey(bc, ((DataMember) last).getName(), false);
        // write out value
        value.writeOut(bc, MODE_VALUE);
        if (type == POST) {
            if (operation != OpDouble.PLUS && operation != OpDouble.MINUS)
                throw new TransformerException("Post only possible with plus or minus " + operation, value.getStart());
            if (operation == PLUS)
                adapter.invokeStatic(Types.OPERATOR, UNARY_POST_PLUS2);
            else if (operation == MINUS)
                adapter.invokeStatic(Types.OPERATOR, UNARY_POST_MINUS2);
        } else if (type == PRE) {
            if (operation == PLUS)
                adapter.invokeStatic(Types.OPERATOR, UNARY_PRE_PLUS2);
            else if (operation == MINUS)
                adapter.invokeStatic(Types.OPERATOR, UNARY_PRE_MINUS2);
            else if (operation == DIVIDE)
                adapter.invokeStatic(Types.OPERATOR, UNARY_PRE_DIVIDE2);
            else if (operation == MULTIPLY)
                adapter.invokeStatic(Types.OPERATOR, UNARY_PRE_MULTIPLY2);
            else if (operation == CONCAT)
                adapter.invokeStatic(Types.OPERATOR, UNARY_PRE_CONCAT2);
        }
        if (operation == CONCAT)
            return Types.STRING;
        // convert from Double to double (if necessary)
        if (mode == MODE_REF) {
            adapter.invokeStatic(Types.CASTER, Methods.METHOD_TO_DOUBLE_FROM_DOUBLE);
            return Types.DOUBLE;
        }
        return Types.DOUBLE_VALUE;
    }
    /*
		 *  undefined scope only with one key (susi++;)
		 */
    // PageContext instance
    adapter.loadArg(0);
    // Collection key Array
    int arrSize = scope != null ? members.size() + 1 : members.size();
    boolean useArray = arrSize > 1 || scope != null;
    if (useArray) {
        ArrayVisitor av = new ArrayVisitor();
        int index = 0;
        av.visitBegin(adapter, Types.COLLECTION_KEY, arrSize);
        Iterator<Member> it = members.iterator();
        Member m;
        DataMember dm;
        if (scope != null) {
            av.visitBeginItem(adapter, index++);
            getFactory().registerKey(bc, getFactory().createLitString(scope), false);
            av.visitEndItem(adapter);
        }
        while (it.hasNext()) {
            av.visitBeginItem(adapter, index++);
            m = it.next();
            if (!(m instanceof DataMember))
                throw new TransformerException("you cannot use a unary operator with a function " + m.getClass().getName(), getStart());
            getFactory().registerKey(bc, ((DataMember) m).getName(), false);
            av.visitEndItem(adapter);
        }
        av.visitEnd();
    } else {
        Member m = members.iterator().next();
        if (!(m instanceof DataMember))
            throw new TransformerException("you cannot use a unary operator with a function " + m.getClass().getName(), getStart());
        getFactory().registerKey(bc, ((DataMember) m).getName(), false);
    }
    if (type == POST) {
        if (operation != OpDouble.PLUS && operation != OpDouble.MINUS)
            throw new TransformerException("Post only possible with plus or minus " + operation, value.getStart());
        value.writeOut(bc, MODE_VALUE);
        if (operation == PLUS)
            adapter.invokeStatic(Types.OPERATOR, useArray ? UNARY_POST_PLUS_N : UNARY_POST_PLUS_1);
        else if (operation == MINUS)
            adapter.invokeStatic(Types.OPERATOR, useArray ? UNARY_POST_MINUS_N : UNARY_POST_MINUS_1);
    } else if (type == PRE) {
        value.writeOut(bc, MODE_VALUE);
        if (operation == PLUS)
            adapter.invokeStatic(Types.OPERATOR, useArray ? UNARY_PRE_PLUS_N : UNARY_PRE_PLUS_1);
        else if (operation == MINUS)
            adapter.invokeStatic(Types.OPERATOR, useArray ? UNARY_PRE_MINUS_N : UNARY_PRE_MINUS_1);
        else if (operation == DIVIDE)
            adapter.invokeStatic(Types.OPERATOR, useArray ? UNARY_PRE_DIVIDE_N : UNARY_PRE_DIVIDE_1);
        else if (operation == MULTIPLY)
            adapter.invokeStatic(Types.OPERATOR, useArray ? UNARY_PRE_MULTIPLY_N : UNARY_PRE_MULTIPLY_1);
        else if (operation == CONCAT)
            adapter.invokeStatic(Types.OPERATOR, useArray ? UNARY_PRE_CONCAT_N : UNARY_PRE_CONCAT_1);
    }
    if (operation == CONCAT)
        return Types.STRING;
    // convert from double to Double (if necessary)
    if (mode == MODE_REF) {
        adapter.invokeStatic(Types.CASTER, Methods.METHOD_TO_DOUBLE_FROM_DOUBLE);
        return Types.DOUBLE;
    }
    return Types.DOUBLE_VALUE;
}
Also used : DataMember(lucee.transformer.expression.var.DataMember) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) CastString(lucee.transformer.bytecode.cast.CastString) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor) DataMember(lucee.transformer.expression.var.DataMember) Member(lucee.transformer.expression.var.Member) TransformerException(lucee.transformer.TransformerException)

Example 7 with Member

use of lucee.transformer.expression.var.Member in project Lucee by lucee.

the class OpElvis method _writeOutPureDataMember.

public Type _writeOutPureDataMember(BytecodeContext bc, int mode) throws TransformerException {
    // TODO use function isNull for this
    GeneratorAdapter adapter = bc.getAdapter();
    Label yes = new Label();
    Label end = new Label();
    List<Member> members = left.getMembers();
    // to array
    Iterator<Member> it = members.iterator();
    List<DataMember> list = new ArrayList<DataMember>();
    while (it.hasNext()) {
        list.add((DataMember) it.next());
    }
    DataMember[] arr = list.toArray(new DataMember[members.size()]);
    ExpressionUtil.visitLine(bc, left.getStart());
    // public static boolean call(PageContext pc , double scope,String[] varNames)
    // pc
    adapter.loadArg(0);
    // scope
    adapter.push((double) left.getScope());
    // varNames
    // all literal string?
    boolean allLiteral = true;
    for (int i = 0; i < arr.length; i++) {
        if (!(arr[i].getName() instanceof Literal))
            allLiteral = false;
    }
    ArrayVisitor av = new ArrayVisitor();
    if (!allLiteral) {
        // String Array
        av.visitBegin(adapter, Types.STRING, arr.length);
        for (int i = 0; i < arr.length; i++) {
            av.visitBeginItem(adapter, i);
            arr[i].getName().writeOut(bc, MODE_REF);
            av.visitEndItem(adapter);
        }
    } else {
        // Collection.Key Array
        av.visitBegin(adapter, Types.COLLECTION_KEY, arr.length);
        for (int i = 0; i < arr.length; i++) {
            av.visitBeginItem(adapter, i);
            getFactory().registerKey(bc, arr[i].getName(), false);
            av.visitEndItem(adapter);
        }
    }
    av.visitEnd();
    // allowNull
    // adapter.push(false);
    // ASMConstants.NULL(adapter);
    // call IsDefined.invoke
    adapter.invokeStatic(ELVIS, allLiteral ? INVOKE_KEY : INVOKE_STR);
    ExpressionUtil.visitLine(bc, left.getEnd());
    adapter.visitJumpInsn(Opcodes.IFEQ, yes);
    // left
    ExpressionUtil.visitLine(bc, left.getStart());
    left.writeOut(bc, MODE_REF);
    ExpressionUtil.visitLine(bc, left.getEnd());
    adapter.visitJumpInsn(Opcodes.GOTO, end);
    // right
    ExpressionUtil.visitLine(bc, right.getStart());
    adapter.visitLabel(yes);
    right.writeOut(bc, MODE_REF);
    ExpressionUtil.visitLine(bc, right.getEnd());
    adapter.visitLabel(end);
    return Types.OBJECT;
}
Also used : Label(org.objectweb.asm.Label) ArrayList(java.util.ArrayList) Literal(lucee.transformer.expression.literal.Literal) DataMember(lucee.transformer.expression.var.DataMember) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor) DataMember(lucee.transformer.expression.var.DataMember) Member(lucee.transformer.expression.var.Member)

Example 8 with Member

use of lucee.transformer.expression.var.Member in project Lucee by lucee.

the class ASMUtil method hasOnlyDataMembers.

public static boolean hasOnlyDataMembers(Variable var) {
    Iterator<Member> it = var.getMembers().iterator();
    Member m;
    while (it.hasNext()) {
        m = it.next();
        if (!(m instanceof DataMember))
            return false;
    }
    return true;
}
Also used : DataMember(lucee.transformer.expression.var.DataMember) DataMember(lucee.transformer.expression.var.DataMember) Member(lucee.transformer.expression.var.Member)

Example 9 with Member

use of lucee.transformer.expression.var.Member in project Lucee by lucee.

the class ExpressionInvoker method _writeOut.

@Override
public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException {
    GeneratorAdapter adapter = bc.getAdapter();
    Type rtn = Types.OBJECT;
    int count = members.size();
    for (int i = 0; i < count; i++) {
        adapter.loadArg(0);
    }
    expr.writeOut(bc, Expression.MODE_REF);
    for (int i = 0; i < count; i++) {
        Member member = members.get(i);
        // Data Member
        if (member instanceof DataMember) {
            ((DataMember) member).getName().writeOut(bc, MODE_REF);
            adapter.invokeVirtual(Types.PAGE_CONTEXT, ((i + 1) == count) ? GET : GET_COLLECTION);
            rtn = Types.OBJECT;
        } else // UDF
        if (member instanceof UDF) {
            UDF udf = (UDF) member;
            udf.getName().writeOut(bc, MODE_REF);
            ExpressionUtil.writeOutExpressionArray(bc, Types.OBJECT, udf.getArguments());
            adapter.invokeVirtual(Types.PAGE_CONTEXT, udf.hasNamedArgs() ? GET_FUNCTION_WITH_NAMED_ARGS : GET_FUNCTION);
            rtn = Types.OBJECT;
        }
    }
    return rtn;
}
Also used : Type(org.objectweb.asm.Type) UDF(lucee.transformer.bytecode.expression.var.UDF) DataMember(lucee.transformer.expression.var.DataMember) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) DataMember(lucee.transformer.expression.var.DataMember) Member(lucee.transformer.expression.var.Member)

Example 10 with Member

use of lucee.transformer.expression.var.Member in project Lucee by lucee.

the class VT method _writeOutCallerUtil.

private Type _writeOutCallerUtil(BytecodeContext bc, int mode) throws TransformerException {
    GeneratorAdapter adapter = bc.getAdapter();
    final int count = countFM + countDM;
    // count 0
    if (count == 0)
        return _writeOutEmpty(bc);
    // pc
    adapter.loadArg(0);
    // collection
    RefInteger startIndex = new RefIntegerImpl();
    _writeOutFirst(bc, (members.get(0)), mode, count == 1, true, defaultValue, startIndex);
    // keys
    Iterator<Member> it = members.iterator();
    ArrayVisitor av = new ArrayVisitor();
    av.visitBegin(adapter, Types.COLLECTION_KEY, countDM - startIndex.toInt());
    int index = 0, i = 0;
    while (it.hasNext()) {
        DataMember member = (DataMember) it.next();
        if (i++ < startIndex.toInt())
            continue;
        av.visitBeginItem(adapter, index++);
        getFactory().registerKey(bc, member.getName(), false);
        av.visitEndItem(bc.getAdapter());
    }
    av.visitEnd();
    // defaultValue
    defaultValue.writeOut(bc, MODE_REF);
    bc.getAdapter().invokeStatic(Types.CALLER_UTIL, CALLER_UTIL_GET);
    return Types.OBJECT;
}
Also used : RefInteger(lucee.commons.lang.types.RefInteger) DataMember(lucee.transformer.expression.var.DataMember) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor) RefIntegerImpl(lucee.commons.lang.types.RefIntegerImpl) DataMember(lucee.transformer.expression.var.DataMember) Member(lucee.transformer.expression.var.Member)

Aggregations

Member (lucee.transformer.expression.var.Member)13 DataMember (lucee.transformer.expression.var.DataMember)11 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)6 Expression (lucee.transformer.expression.Expression)5 Literal (lucee.transformer.expression.literal.Literal)5 ExprString (lucee.transformer.expression.ExprString)4 Variable (lucee.transformer.expression.var.Variable)4 ArrayList (java.util.ArrayList)3 TransformerException (lucee.transformer.TransformerException)3 BIF (lucee.transformer.bytecode.expression.var.BIF)3 ArrayVisitor (lucee.transformer.bytecode.visitor.ArrayVisitor)3 LitString (lucee.transformer.expression.literal.LitString)3 Type (org.objectweb.asm.Type)3 Body (lucee.transformer.bytecode.Body)2 Statement (lucee.transformer.bytecode.Statement)2 CastString (lucee.transformer.bytecode.cast.CastString)2 Argument (lucee.transformer.bytecode.expression.var.Argument)2 FunctionMember (lucee.transformer.bytecode.expression.var.FunctionMember)2 UDF (lucee.transformer.bytecode.expression.var.UDF)2 PrintOut (lucee.transformer.bytecode.statement.PrintOut)2