use of org.objectweb.asm.Type in project Lucee by lucee.
the class VT method _writeOutFirstBIF.
static Type _writeOutFirstBIF(BytecodeContext bc, BIF bif, int mode, boolean last, Position line) throws TransformerException {
double start = SystemUtil.millis();
GeneratorAdapter adapter = bc.getAdapter();
adapter.loadArg(0);
// class
ClassDefinition bifCD = bif.getClassDefinition();
Class clazz = null;
try {
clazz = bifCD.getClazz();
} catch (Exception e) {
SystemOut.printDate(e);
}
Type rtnType = Types.toType(bif.getReturnType());
if (rtnType == Types.VOID)
rtnType = Types.STRING;
// arguments
Argument[] args = bif.getArguments();
Type[] argTypes;
// MUST setting this to false need to work !!!
boolean core = bif.getFlf().isCore();
if (bif.getArgType() == FunctionLibFunction.ARG_FIX && !bifCD.isBundle() && core) {
if (isNamed(bif.getFlf().getName(), args)) {
NamedArgument[] nargs = toNamedArguments(args);
String[] names = new String[nargs.length];
// get all names
for (int i = 0; i < nargs.length; i++) {
names[i] = getName(nargs[i].getName());
}
ArrayList<FunctionLibFunctionArg> list = bif.getFlf().getArg();
Iterator<FunctionLibFunctionArg> it = list.iterator();
argTypes = new Type[list.size() + 1];
argTypes[0] = Types.PAGE_CONTEXT;
FunctionLibFunctionArg flfa;
int index = 0;
VT vt;
while (it.hasNext()) {
flfa = it.next();
vt = getMatchingValueAndType(bc.getFactory(), flfa, nargs, names, line);
if (vt.index != -1)
names[vt.index] = null;
argTypes[++index] = Types.toType(vt.type);
if (vt.value == null)
ASMConstants.NULL(bc.getAdapter());
else
vt.value.writeOut(bc, Types.isPrimitiveType(argTypes[index]) ? MODE_VALUE : MODE_REF);
}
for (int y = 0; y < names.length; y++) {
if (names[y] != null) {
TransformerException bce = new TransformerException("argument [" + names[y] + "] is not allowed for function [" + bif.getFlf().getName() + "]", args[y].getStart());
UDFUtil.addFunctionDoc(bce, bif.getFlf());
throw bce;
}
}
} else {
argTypes = new Type[args.length + 1];
argTypes[0] = Types.PAGE_CONTEXT;
for (int y = 0; y < args.length; y++) {
argTypes[y + 1] = Types.toType(args[y].getStringType());
args[y].writeOutValue(bc, Types.isPrimitiveType(argTypes[y + 1]) ? MODE_VALUE : MODE_REF);
}
// if no method exists for the exact match of arguments, call the method with all arguments (when exists)
if (methodExists(clazz, "call", argTypes, rtnType) == Boolean.FALSE) {
ArrayList<FunctionLibFunctionArg> _args = bif.getFlf().getArg();
Type[] tmp = new Type[_args.size() + 1];
// fill the existing
for (int i = 0; i < argTypes.length; i++) {
tmp[i] = argTypes[i];
}
// get the rest with default values
FunctionLibFunctionArg flfa;
VT def;
for (int i = argTypes.length; i < tmp.length; i++) {
flfa = _args.get(i - 1);
tmp[i] = Types.toType(flfa.getTypeAsString());
def = getDefaultValue(bc.getFactory(), flfa);
if (def.value != null)
def.value.writeOut(bc, Types.isPrimitiveType(tmp[i]) ? MODE_VALUE : MODE_REF);
else
ASMConstants.NULL(bc.getAdapter());
}
argTypes = tmp;
}
}
} else // Arg Type DYN or bundle based
{
// /////////////////////////////////////////////////////////////
if (bif.getArgType() == FunctionLibFunction.ARG_FIX) {
if (isNamed(bif.getFlf().getName(), args)) {
NamedArgument[] nargs = toNamedArguments(args);
String[] names = getNames(nargs);
ArrayList<FunctionLibFunctionArg> list = bif.getFlf().getArg();
Iterator<FunctionLibFunctionArg> it = list.iterator();
LinkedList<Argument> tmpArgs = new LinkedList<Argument>();
LinkedList<Boolean> nulls = new LinkedList<Boolean>();
FunctionLibFunctionArg flfa;
VT vt;
while (it.hasNext()) {
flfa = it.next();
vt = getMatchingValueAndType(bc.getFactory(), flfa, nargs, names, line);
if (vt.index != -1)
names[vt.index] = null;
if (vt.value == null)
// has to by any otherwise a caster is set
tmpArgs.add(new Argument(bif.getFactory().createNull(), "any"));
else
tmpArgs.add(new Argument(vt.value, vt.type));
nulls.add(vt.value == null);
}
for (int y = 0; y < names.length; y++) {
if (names[y] != null) {
TransformerException bce = new TransformerException("argument [" + names[y] + "] is not allowed for function [" + bif.getFlf().getName() + "]", args[y].getStart());
UDFUtil.addFunctionDoc(bce, bif.getFlf());
throw bce;
}
}
// remove null at the end
Boolean tmp;
while ((tmp = nulls.pollLast()) != null) {
if (!tmp.booleanValue())
break;
tmpArgs.pollLast();
}
args = tmpArgs.toArray(new Argument[tmpArgs.size()]);
}
}
// /////////////////////////////////////////////////////////////
argTypes = new Type[2];
argTypes[0] = Types.PAGE_CONTEXT;
argTypes[1] = Types.OBJECT_ARRAY;
ExpressionUtil.writeOutExpressionArray(bc, Types.OBJECT, args);
}
// core
if (core && !bifCD.isBundle()) {
adapter.invokeStatic(Type.getType(clazz), new Method("call", rtnType, argTypes));
} else // external
{
// className
if (bifCD.getClassName() != null)
adapter.push(bifCD.getClassName());
else
ASMConstants.NULL(adapter);
if (// bundle name
bifCD.getName() != null)
// bundle name
adapter.push(bifCD.getName());
else
ASMConstants.NULL(adapter);
if (// bundle version
bifCD.getVersionAsString() != null)
// bundle version
adapter.push(bifCD.getVersionAsString());
else
ASMConstants.NULL(adapter);
adapter.invokeStatic(Types.FUNCTION_HANDLER_POOL, INVOKE);
rtnType = Types.OBJECT;
}
if (mode == MODE_REF || !last) {
if (Types.isPrimitiveType(rtnType)) {
adapter.invokeStatic(Types.CASTER, new Method("toRef", Types.toRefType(rtnType), new Type[] { rtnType }));
rtnType = Types.toRefType(rtnType);
}
}
return rtnType;
}
use of org.objectweb.asm.Type in project Lucee by lucee.
the class VT method _writeOut.
private Type _writeOut(BytecodeContext bc, int mode, Boolean asCollection) throws TransformerException {
final GeneratorAdapter adapter = bc.getAdapter();
final int count = countFM + countDM;
// count 0
if (count == 0)
return _writeOutEmpty(bc);
boolean doOnlyScope = scope == Scope.SCOPE_LOCAL;
// boolean last;
int c = 0;
for (int i = doOnlyScope ? 0 : 1; i < count; i++) {
Member member = (members.get((count - 1) - c));
c++;
adapter.loadArg(0);
if (member.getSafeNavigated() && member instanceof UDF)
adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
}
Type rtn = _writeOutFirst(bc, (members.get(0)), mode, count == 1, doOnlyScope, null, null);
// pc.get(
for (int i = doOnlyScope ? 0 : 1; i < count; i++) {
Member member = (members.get(i));
boolean last = (i + 1) == count;
// Data Member
if (member instanceof DataMember) {
ExprString name = ((DataMember) member).getName();
if (last && ASMUtil.isDotKey(name)) {
LitString ls = (LitString) name;
if (ls.getString().equalsIgnoreCase("RECORDCOUNT")) {
adapter.invokeStatic(Types.VARIABLE_UTIL_IMPL, RECORDCOUNT);
} else if (ls.getString().equalsIgnoreCase("CURRENTROW")) {
adapter.invokeStatic(Types.VARIABLE_UTIL_IMPL, CURRENTROW);
} else if (ls.getString().equalsIgnoreCase("COLUMNLIST")) {
adapter.invokeStatic(Types.VARIABLE_UTIL_IMPL, COLUMNLIST);
} else {
getFactory().registerKey(bc, name, false);
// safe nav
int type;
if (member.getSafeNavigated()) {
Expression val = member.getSafeNavigatedValue();
if (val == null)
ASMConstants.NULL(adapter);
else
val.writeOut(bc, Expression.MODE_REF);
type = THREE;
} else
type = TWO;
adapter.invokeVirtual(Types.PAGE_CONTEXT, asCollection(asCollection, last) ? GET_COLLECTION[type] : GET[type]);
}
} else {
getFactory().registerKey(bc, name, false);
// safe nav
int type;
if (member.getSafeNavigated()) {
Expression val = member.getSafeNavigatedValue();
if (val == null)
ASMConstants.NULL(adapter);
else
val.writeOut(bc, Expression.MODE_REF);
type = THREE;
} else
type = TWO;
adapter.invokeVirtual(Types.PAGE_CONTEXT, asCollection(asCollection, last) ? GET_COLLECTION[type] : GET[type]);
}
rtn = Types.OBJECT;
} else // UDF
if (member instanceof UDF) {
rtn = _writeOutUDF(bc, (UDF) member);
}
}
return rtn;
}
use of org.objectweb.asm.Type in project ZenScript by CraftTweaker.
the class ZenTypeFunction method getCastingRule.
@Override
public ICastingRule getCastingRule(ZenType type, IEnvironmentGlobal environment) {
if (implementedInterfaces.containsKey(type)) {
return implementedInterfaces.get(type);
}
Class cls = type.toJavaClass();
System.out.println("Can cast this function to " + cls.getName() + "?");
if (cls.isInterface() && cls.getMethods().length == 1) {
// this is a functional interface
// do the method signatures match?
Method method = cls.getMethods()[0];
ZenType methodReturnType = environment.getType(method.getGenericReturnType());
ICastingRule returnCastingRule = null;
if (!returnType.equals(methodReturnType)) {
returnCastingRule = returnType.getCastingRule(environment.getType(method.getGenericReturnType()), environment);
if (returnCastingRule == null) {
System.out.println("Return types don't match");
return null;
}
}
java.lang.reflect.Type[] methodParameters = method.getGenericParameterTypes();
if (methodParameters.length < argumentTypes.length) {
System.out.println("Argument count doesn't match");
return null;
}
ICastingRule[] argumentCastingRules = new ICastingRule[argumentTypes.length];
for (int i = 0; i < argumentCastingRules.length; i++) {
ZenType argumentType = environment.getType(methodParameters[i]);
if (!argumentType.equals(argumentTypes[i])) {
argumentCastingRules[i] = argumentType.getCastingRule(argumentTypes[i], environment);
if (argumentCastingRules[i] == null) {
System.out.println("Argument " + i + " doesn't match");
System.out.println("Cannot cast " + argumentType.getName() + " to " + argumentTypes[i].getName());
return null;
}
}
}
CastingRuleMatchedFunction castingRule = new CastingRuleMatchedFunction(this, type, returnCastingRule, argumentCastingRules);
implementedInterfaces.put(type, castingRule);
System.out.println("Can cast this function");
return castingRule;
}
return null;
}
use of org.objectweb.asm.Type in project ZenScript by CraftTweaker.
the class StatementReturn method compile.
@Override
public void compile(IEnvironmentMethod environment) {
environment.getOutput().position(getPosition());
if (expression == null) {
environment.getOutput().ret();
} else {
Expression cExpression = expression.compile(environment, returnType).eval(environment);
cExpression.compile(true, environment);
Type returnType = cExpression.getType().toASMType();
environment.getOutput().returnType(returnType);
}
}
use of org.objectweb.asm.Type in project ZenScript by CraftTweaker.
the class ExpressionArray method compile.
@Override
public void compile(boolean result, IEnvironmentMethod environment) {
ZenType baseType = type.getBaseType();
Type asmBaseType = type.getBaseType().toASMType();
MethodOutput output = environment.getOutput();
output.constant(contents.length);
output.newArray(asmBaseType);
for (int i = 0; i < contents.length; i++) {
output.dup();
output.constant(i);
contents[i].cast(this.getPosition(), environment, baseType).compile(result, environment);
output.arrayStore(asmBaseType);
}
}
Aggregations