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;
}
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;
}
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;
}
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;
}
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;
}
Aggregations