use of lucee.transformer.bytecode.visitor.ArrayVisitor in project Lucee by lucee.
the class NamedArgument method _writeOut.
@Override
public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException {
int form = VALUE;
int type = STRING;
if (name instanceof Variable && !((Variable) name).fromHash()) {
GeneratorAdapter adapter = bc.getAdapter();
String[] arr = VariableString.variableToStringArray((Variable) name, true);
if (arr.length > 1) {
form = ARRAY;
ArrayVisitor av = new ArrayVisitor();
av.visitBegin(adapter, Types.STRING, arr.length);
for (int y = 0; y < arr.length; y++) {
av.visitBeginItem(adapter, y);
adapter.push(varKeyUpperCase ? arr[y].toUpperCase() : arr[y]);
av.visitEndItem(bc.getAdapter());
}
av.visitEnd();
} else {
// VariableString.toExprString(name).writeOut(bc, MODE_REF);
String str = VariableString.variableToString((Variable) name, true);
name = bc.getFactory().createLitString(varKeyUpperCase ? str.toUpperCase() : str);
getFactory().registerKey(bc, VariableString.toExprString(name), false);
type = KEY;
}
} else {
getFactory().registerKey(bc, name.getFactory().toExprString(name), false);
type = KEY;
}
// name.writeOut(bc, MODE_REF);
super._writeOut(bc, MODE_REF);
// bc.getAdapter().push(variableString);
bc.getAdapter().invokeStatic(Types.FUNCTION_VALUE_IMPL, NEW_INSTANCE[type][form]);
return Types.FUNCTION_VALUE;
}
use of lucee.transformer.bytecode.visitor.ArrayVisitor 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.bytecode.visitor.ArrayVisitor 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.bytecode.visitor.ArrayVisitor in project Lucee by lucee.
the class JavaProxyFactory method _createMethod.
private static void _createMethod(ClassWriter cw, Map<String, Class> mDone, Method src, String className) throws IOException {
final Class<?>[] classArgs = src.getParameterTypes();
final Class<?> classRtn = src.getReturnType();
String str = src.getName() + "(" + Reflector.getDspMethods(classArgs) + ")";
Class rtnClass = mDone.get(str);
if (rtnClass != null) {
if (rtnClass != classRtn)
throw new IOException("there is a conflict with method [" + str + "], this method is declared more than once with different return types.");
return;
}
mDone.put(str, classRtn);
Type[] typeArgs = ASMUtil.toTypes(classArgs);
Type typeRtn = Type.getType(classRtn);
org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(src.getName(), typeRtn, typeArgs);
GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, method, null, null, cw);
// BytecodeContext bc = new BytecodeContext(statConstr,constr,null,null,keys,cw,className,adapter,method,writeLog);
Label start = adapter.newLabel();
adapter.visitLabel(start);
// if the result of "call" need castring, we have to do this here
if (needCastring(classRtn)) {
adapter.invokeStatic(CFML_ENGINE_FACTORY, GET_INSTANCE);
adapter.invokeInterface(CFML_ENGINE, GET_JAVA_PROXY_UTIL);
adapter.checkCast(JAVA_PROXY_UTIL);
}
adapter.invokeStatic(CFML_ENGINE_FACTORY, GET_INSTANCE);
adapter.invokeInterface(CFML_ENGINE, GET_JAVA_PROXY_UTIL);
adapter.checkCast(JAVA_PROXY_UTIL);
// Java Proxy.call(cfc,"add",new Object[]{arg0})
// config (first argument)
adapter.visitVarInsn(Opcodes.ALOAD, 0);
adapter.visitFieldInsn(Opcodes.GETFIELD, className, "config", CONFIG_WEB_NAME);
// cfc (second argument)
adapter.visitVarInsn(Opcodes.ALOAD, 0);
adapter.visitFieldInsn(Opcodes.GETFIELD, className, "cfc", COMPONENT_NAME);
// name (3th argument)
adapter.push(src.getName());
// arguments (4th argument)
ArrayVisitor av = new ArrayVisitor();
av.visitBegin(adapter, Types.OBJECT, typeArgs.length);
for (int y = 0; y < typeArgs.length; y++) {
av.visitBeginItem(adapter, y);
adapter.invokeStatic(CFML_ENGINE_FACTORY, GET_INSTANCE);
adapter.invokeInterface(CFML_ENGINE, GET_JAVA_PROXY_UTIL);
adapter.checkCast(JAVA_PROXY_UTIL);
adapter.loadArg(y);
if (classArgs[y] == boolean.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, _BOOLEAN);
else if (classArgs[y] == byte.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, _BYTE);
else if (classArgs[y] == char.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, _CHAR);
else if (classArgs[y] == double.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, _DOUBLE);
else if (classArgs[y] == float.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, _FLOAT);
else if (classArgs[y] == int.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, _INT);
else if (classArgs[y] == long.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, _LONG);
else if (classArgs[y] == short.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, _SHORT);
else
adapter.invokeInterface(JAVA_PROXY_UTIL, _OBJECT);
av.visitEndItem(adapter);
}
av.visitEnd();
adapter.invokeInterface(JAVA_PROXY_UTIL, CALL);
// CFMLEngineFactory.getInstance().getCastUtil().toBooleanValue(o);
// Java Proxy.to...(...);
int rtn = Opcodes.IRETURN;
if (classRtn == boolean.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_BOOLEAN);
else if (classRtn == byte.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_BYTE);
else if (classRtn == char.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_CHAR);
else if (classRtn == double.class) {
rtn = Opcodes.DRETURN;
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_DOUBLE);
} else if (classRtn == float.class) {
rtn = Opcodes.FRETURN;
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_FLOAT);
} else if (classRtn == int.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_INT);
else if (classRtn == long.class) {
rtn = Opcodes.LRETURN;
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_LONG);
} else if (classRtn == short.class)
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_SHORT);
else if (classRtn == void.class) {
rtn = Opcodes.RETURN;
adapter.pop();
} else if (classRtn == String.class) {
rtn = Opcodes.ARETURN;
adapter.invokeInterface(JAVA_PROXY_UTIL, TO_STRING);
} else {
rtn = Opcodes.ARETURN;
adapter.checkCast(typeRtn);
}
adapter.visitInsn(rtn);
adapter.endMethod();
}
use of lucee.transformer.bytecode.visitor.ArrayVisitor in project Lucee by lucee.
the class SourceLastModifiedClassAdapter method execute.
/**
* convert the Page Object to java bytecode
* @param className name of the genrated class (only necessary when Page object has no PageSource reference)
* @return
* @throws TransformerException
*/
public byte[] execute(String className) throws TransformerException {
// not exists in any case, so every usage must have a plan b for not existence
PageSource optionalPS = sourceCode instanceof PageSourceCode ? ((PageSourceCode) sourceCode).getPageSource() : null;
List<LitString> keys = new ArrayList<LitString>();
ClassWriter cw = ASMUtil.getClassWriter();
ArrayList<String> imports = new ArrayList<String>();
getImports(imports, this);
// look for component if necessary
TagCIObject comp = getTagCFObject(null);
// in case we have a sub component
if (className == null) {
if (optionalPS == null)
throw new IllegalArgumentException("when Page object has no PageSource, a className is necessary");
className = optionalPS.getClassName();
}
if (comp != null)
className = createSubClass(className, comp.getName(), sourceCode.getDialect());
className = className.replace('.', '/');
this.className = className;
// parent
// "lucee/runtime/Page";
String parent = PageImpl.class.getName();
if (// "lucee/runtime/ComponentPage";
isComponent(comp))
// "lucee/runtime/ComponentPage";
parent = ComponentPageImpl.class.getName();
else // "lucee/runtime/InterfacePage";
if (isInterface(comp))
parent = InterfacePageImpl.class.getName();
parent = parent.replace('.', '/');
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, className, null, parent, null);
if (optionalPS != null) {
// we use full path when FD is enabled
String path = config.allowRequestTimeout() ? optionalPS.getRealpathWithVirtual() : optionalPS.getPhyscalFile().getAbsolutePath();
// when adding more use ; as delimiter
cw.visitSource(path, null);
// cw.visitSource(optionalPS.getPhyscalFile().getAbsolutePath(),
// "rel:"+optionalPS.getRealpathWithVirtual()); // when adding more use ; as delimiter
} else {
// cw.visitSource("","rel:");
}
// static constructor
// GeneratorAdapter statConstrAdapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC,STATIC_CONSTRUCTOR,null,null,cw);
// StaticConstrBytecodeContext statConstr = null;//new BytecodeContext(null,null,this,externalizer,keys,cw,name,statConstrAdapter,STATIC_CONSTRUCTOR,writeLog(),suppressWSbeforeArg);
// constructor
GeneratorAdapter constrAdapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC, CONSTRUCTOR_PS, null, null, cw);
ConstrBytecodeContext constr = new ConstrBytecodeContext(optionalPS, this, keys, cw, className, constrAdapter, CONSTRUCTOR_PS, writeLog(), suppressWSbeforeArg, output, returnValue);
constrAdapter.loadThis();
Type t;
if (isComponent(comp)) {
t = Types.COMPONENT_PAGE_IMPL;
// extends
// Attribute attr = comp.getAttribute("extends");
// if(attr!=null) ExpressionUtil.writeOutSilent(attr.getValue(),constr, Expression.MODE_REF);
// else constrAdapter.push("");
constrAdapter.invokeConstructor(t, CONSTRUCTOR);
} else if (isInterface(comp)) {
t = Types.INTERFACE_PAGE_IMPL;
constrAdapter.invokeConstructor(t, CONSTRUCTOR);
} else {
t = Types.PAGE_IMPL;
constrAdapter.invokeConstructor(t, CONSTRUCTOR);
}
// call _init()
constrAdapter.visitVarInsn(Opcodes.ALOAD, 0);
constrAdapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, constr.getClassName(), "initKeys", "()V");
// private static ImportDefintion[] test=new ImportDefintion[]{...};
{
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, "imports", "[Llucee/runtime/component/ImportDefintion;", null, null);
fv.visitEnd();
constrAdapter.visitVarInsn(Opcodes.ALOAD, 0);
ArrayVisitor av = new ArrayVisitor();
av.visitBegin(constrAdapter, Types.IMPORT_DEFINITIONS, imports.size());
int index = 0;
Iterator<String> it = imports.iterator();
while (it.hasNext()) {
av.visitBeginItem(constrAdapter, index++);
constrAdapter.push(it.next());
ASMConstants.NULL(constrAdapter);
constrAdapter.invokeStatic(Types.IMPORT_DEFINITIONS_IMPL, ID_GET_INSTANCE);
av.visitEndItem(constrAdapter);
}
av.visitEnd();
constrAdapter.visitFieldInsn(Opcodes.PUTFIELD, className, "imports", "[Llucee/runtime/component/ImportDefintion;");
}
// getVersion
GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, VERSION, null, null, cw);
adapter.push(version);
adapter.returnValue();
adapter.endMethod();
// public ImportDefintion[] getImportDefintions()
if (imports.size() > 0) {
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, GET_IMPORT_DEFINITIONS, null, null, cw);
adapter.visitVarInsn(Opcodes.ALOAD, 0);
adapter.visitFieldInsn(Opcodes.GETFIELD, className, "imports", "[Llucee/runtime/component/ImportDefintion;");
adapter.returnValue();
adapter.endMethod();
} else {
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, GET_IMPORT_DEFINITIONS, null, null, cw);
adapter.visitInsn(Opcodes.ICONST_0);
adapter.visitTypeInsn(Opcodes.ANEWARRAY, "lucee/runtime/component/ImportDefintion");
adapter.returnValue();
adapter.endMethod();
}
// getSourceLastModified
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, LAST_MOD, null, null, cw);
adapter.push(lastModifed);
adapter.returnValue();
adapter.endMethod();
// getSourceLength
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, LENGTH, null, null, cw);
adapter.push(length);
adapter.returnValue();
adapter.endMethod();
// getCompileTime
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, COMPILE_TIME, null, null, cw);
adapter.push(System.currentTimeMillis());
adapter.returnValue();
adapter.endMethod();
// getHash
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, HASH, null, null, cw);
adapter.push(hash);
adapter.returnValue();
adapter.endMethod();
if (comp != null) {
writeOutStaticConstructor(constr, keys, cw, comp, className);
}
// newInstance/initComponent/call
if (isComponent()) {
writeOutNewComponent(constr, keys, cw, comp, className);
writeOutInitComponent(constr, keys, cw, comp, className);
} else if (isInterface()) {
writeOutNewInterface(constr, keys, cw, comp, className);
writeOutInitInterface(constr, keys, cw, comp, className);
} else {
writeOutCall(constr, keys, cw, className);
}
// write UDFProperties to constructor
// writeUDFProperties(bc,funcs,pageType);
// udfCall
Function[] functions = getFunctions();
ConditionVisitor cv;
DecisionIntVisitor div;
// less/equal than 10 functions
if (isInterface()) {
} else if (functions.length <= 10) {
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, UDF_CALL, null, new Type[] { Types.THROWABLE }, cw);
BytecodeContext bc = new BytecodeContext(optionalPS, constr, this, keys, cw, className, adapter, UDF_CALL, writeLog(), suppressWSbeforeArg, output, returnValue);
if (functions.length == 0) {
} else if (functions.length == 1) {
ExpressionUtil.visitLine(bc, functions[0].getStart());
functions[0].getBody().writeOut(bc);
ExpressionUtil.visitLine(bc, functions[0].getEnd());
} else
writeOutUdfCallInner(bc, functions, 0, functions.length);
adapter.visitInsn(Opcodes.ACONST_NULL);
adapter.returnValue();
adapter.endMethod();
} else // more than 10 functions
{
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, UDF_CALL, null, new Type[] { Types.THROWABLE }, cw);
BytecodeContext bc = new BytecodeContext(optionalPS, constr, this, keys, cw, className, adapter, UDF_CALL, writeLog(), suppressWSbeforeArg, output, returnValue);
cv = new ConditionVisitor();
cv.visitBefore();
int count = 0;
for (int i = 0; i < functions.length; i += 10) {
cv.visitWhenBeforeExpr();
div = new DecisionIntVisitor();
div.visitBegin();
adapter.loadArg(2);
div.visitLT();
adapter.push(i + 10);
div.visitEnd(bc);
cv.visitWhenAfterExprBeforeBody(bc);
adapter.visitVarInsn(Opcodes.ALOAD, 0);
adapter.visitVarInsn(Opcodes.ALOAD, 1);
adapter.visitVarInsn(Opcodes.ALOAD, 2);
adapter.visitVarInsn(Opcodes.ILOAD, 3);
adapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, createFunctionName(++count), "(Llucee/runtime/PageContext;Llucee/runtime/type/UDF;I)Ljava/lang/Object;");
// adapter.returnValue();
adapter.visitInsn(Opcodes.ARETURN);
cv.visitWhenAfterBody(bc);
}
cv.visitAfter(bc);
adapter.visitInsn(Opcodes.ACONST_NULL);
adapter.returnValue();
adapter.endMethod();
count = 0;
Method innerCall;
for (int i = 0; i < functions.length; i += 10) {
innerCall = new Method(createFunctionName(++count), Types.OBJECT, new Type[] { Types.PAGE_CONTEXT, USER_DEFINED_FUNCTION, Types.INT_VALUE });
adapter = new GeneratorAdapter(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, innerCall, null, new Type[] { Types.THROWABLE }, cw);
writeOutUdfCallInner(new BytecodeContext(optionalPS, constr, this, keys, cw, className, adapter, innerCall, writeLog(), suppressWSbeforeArg, output, returnValue), functions, i, i + 10 > functions.length ? functions.length : i + 10);
adapter.visitInsn(Opcodes.ACONST_NULL);
adapter.returnValue();
adapter.endMethod();
}
}
// threadCall
TagThread[] threads = getThreads();
if (true) {
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, THREAD_CALL, null, new Type[] { Types.THROWABLE }, cw);
if (threads.length > 0)
writeOutThreadCallInner(new BytecodeContext(optionalPS, constr, this, keys, cw, className, adapter, THREAD_CALL, writeLog(), suppressWSbeforeArg, output, returnValue), threads, 0, threads.length);
// adapter.visitInsn(Opcodes.ACONST_NULL);
adapter.returnValue();
adapter.endMethod();
}
// less/equal than 10 functions
if (isInterface()) {
} else if (functions.length <= 10) {
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, UDF_DEFAULT_VALUE, null, new Type[] { Types.PAGE_EXCEPTION }, cw);
if (functions.length > 0)
writeUdfDefaultValueInner(new BytecodeContext(optionalPS, constr, this, keys, cw, className, adapter, UDF_DEFAULT_VALUE, writeLog(), suppressWSbeforeArg, output, returnValue), functions, 0, functions.length);
adapter.loadArg(DEFAULT_VALUE);
adapter.returnValue();
adapter.endMethod();
} else {
adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, UDF_DEFAULT_VALUE, null, new Type[] { Types.PAGE_EXCEPTION }, cw);
BytecodeContext bc = new BytecodeContext(optionalPS, constr, this, keys, cw, className, adapter, UDF_DEFAULT_VALUE, writeLog(), suppressWSbeforeArg, output, returnValue);
cv = new ConditionVisitor();
cv.visitBefore();
int count = 0;
for (int i = 0; i < functions.length; i += 10) {
cv.visitWhenBeforeExpr();
div = new DecisionIntVisitor();
div.visitBegin();
adapter.loadArg(1);
div.visitLT();
adapter.push(i + 10);
div.visitEnd(bc);
cv.visitWhenAfterExprBeforeBody(bc);
adapter.visitVarInsn(Opcodes.ALOAD, 0);
adapter.visitVarInsn(Opcodes.ALOAD, 1);
adapter.visitVarInsn(Opcodes.ILOAD, 2);
adapter.visitVarInsn(Opcodes.ILOAD, 3);
adapter.visitVarInsn(Opcodes.ALOAD, 4);
adapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, "udfDefaultValue" + (++count), "(Llucee/runtime/PageContext;IILjava/lang/Object;)Ljava/lang/Object;");
// adapter.returnValue();
adapter.visitInsn(Opcodes.ARETURN);
cv.visitWhenAfterBody(bc);
}
cv.visitAfter(bc);
adapter.visitInsn(Opcodes.ACONST_NULL);
adapter.returnValue();
adapter.endMethod();
count = 0;
Method innerDefaultValue;
for (int i = 0; i < functions.length; i += 10) {
innerDefaultValue = new Method("udfDefaultValue" + (++count), Types.OBJECT, new Type[] { Types.PAGE_CONTEXT, Types.INT_VALUE, Types.INT_VALUE, Types.OBJECT });
adapter = new GeneratorAdapter(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, innerDefaultValue, null, new Type[] { Types.PAGE_EXCEPTION }, cw);
writeUdfDefaultValueInner(new BytecodeContext(optionalPS, constr, this, keys, cw, className, adapter, innerDefaultValue, writeLog(), suppressWSbeforeArg, output, returnValue), functions, i, i + 10 > functions.length ? functions.length : i + 10);
adapter.loadArg(DEFAULT_VALUE);
// adapter.visitInsn(Opcodes.ACONST_NULL);
adapter.returnValue();
adapter.endMethod();
}
}
// CONSTRUCTOR
List<Data> udfProperties = constr.getUDFProperties();
Iterator<Data> it = udfProperties.iterator();
String udfpropsClassName = Types.UDF_PROPERTIES_ARRAY.toString();
// new UDFProperties Array
constrAdapter.visitVarInsn(Opcodes.ALOAD, 0);
constrAdapter.push(udfProperties.size());
constrAdapter.newArray(Types.UDF_PROPERTIES);
constrAdapter.visitFieldInsn(Opcodes.PUTFIELD, getClassName(), "udfs", udfpropsClassName);
// set item
Data data;
while (it.hasNext()) {
data = it.next();
constrAdapter.visitVarInsn(Opcodes.ALOAD, 0);
constrAdapter.visitFieldInsn(Opcodes.GETFIELD, constr.getClassName(), "udfs", Types.UDF_PROPERTIES_ARRAY.toString());
constrAdapter.push(data.arrayIndex);
data.function.createUDFProperties(constr, data.valueIndex, data.type);
constrAdapter.visitInsn(Opcodes.AASTORE);
}
// setPageSource(pageSource);
constrAdapter.visitVarInsn(Opcodes.ALOAD, 0);
constrAdapter.visitVarInsn(Opcodes.ALOAD, 1);
constrAdapter.invokeVirtual(t, SET_PAGE_SOURCE);
constrAdapter.returnValue();
constrAdapter.endMethod();
// INIT KEYS
{
GeneratorAdapter aInit = new GeneratorAdapter(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, INIT_KEYS, null, null, cw);
BytecodeContext bcInit = new BytecodeContext(optionalPS, constr, this, keys, cw, className, aInit, INIT_KEYS, writeLog(), suppressWSbeforeArg, output, returnValue);
registerFields(bcInit, keys);
aInit.returnValue();
aInit.endMethod();
}
// set field subs
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, "subs", "[Llucee/runtime/CIPage;", null, null);
fv.visitEnd();
// create sub components/interfaces
if (comp != null && comp.isMain()) {
List<TagCIObject> subs = getSubs(null);
if (!ArrayUtil.isEmpty(subs)) {
Iterator<TagCIObject> _it = subs.iterator();
TagCIObject tc;
while (_it.hasNext()) {
tc = _it.next();
tc.writeOut(this);
}
writeGetSubPages(cw, className, subs, sourceCode.getDialect());
}
}
return cw.toByteArray();
}
Aggregations