use of org.mvel2.compiler.Accessor in project mvel by mikebrock.
the class ASMAccessorOptimizer method propHandlerByteCodePut.
private void propHandlerByteCodePut(String property, Object ctx, Class handler, Object value) {
PropertyHandler ph = getPropertyHandler(handler);
if (ph instanceof ProducesBytecode) {
assert debug("<<3rd-Party Code Generation>>");
((ProducesBytecode) ph).produceBytecodePut(mv, property, variableFactory);
ph.setProperty(property, ctx, variableFactory, value);
} else {
throw new RuntimeException("unable to compileShared: custom accessor does not support producing bytecode: " + ph.getClass().getName());
}
}
use of org.mvel2.compiler.Accessor in project mvel by mikebrock.
the class ReflectiveAccessorOptimizer method optimizeSetAccessor.
public Accessor optimizeSetAccessor(ParserContext pCtx, char[] property, int start, int offset, Object ctx, Object thisRef, VariableResolverFactory factory, boolean rootThisRef, Object value, Class ingressType) {
this.rootNode = this.currNode = null;
this.expr = property;
this.start = start;
this.first = true;
this.length = start + offset;
this.ctx = ctx;
this.thisRef = thisRef;
this.variableFactory = factory;
this.ingressType = ingressType;
char[] root = null;
int split = findLastUnion();
PropertyVerifier verifier = new PropertyVerifier(property, this.pCtx = pCtx);
if (split != -1) {
root = subset(property, 0, split++);
//todo: must use the property verifier.
property = subset(property, split, property.length - split);
}
if (root != null) {
this.length = end = (this.expr = root).length;
compileGetChain();
ctx = this.val;
}
if (ctx == null) {
throw new PropertyAccessException("could not access property: " + new String(property, this.start, length) + "; parent is null: " + new String(expr), expr, this.start);
}
try {
this.length = end = (this.expr = property).length;
int st;
this.cursor = st = 0;
skipWhitespace();
if (collection) {
st = cursor;
if (cursor == end)
throw new PropertyAccessException("unterminated '['", expr, this.start);
if (scanTo(']'))
throw new PropertyAccessException("unterminated '['", expr, this.start);
String ex = new String(property, st, cursor - st);
if (ctx instanceof Map) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Map.class)) {
propHandlerSet(ex, ctx, Map.class, value);
} else {
//noinspection unchecked
((Map) ctx).put(eval(ex, ctx, variableFactory), convert(value, returnType = verifier.analyze()));
addAccessorNode(new MapAccessorNest(ex, returnType));
}
return rootNode;
} else if (ctx instanceof List) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(List.class)) {
propHandlerSet(ex, ctx, List.class, value);
} else {
//noinspection unchecked
((List) ctx).set(eval(ex, ctx, variableFactory, Integer.class), convert(value, returnType = verifier.analyze()));
addAccessorNode(new ListAccessorNest(ex, returnType));
}
return rootNode;
} else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(ctx.getClass())) {
propHandlerSet(ex, ctx, ctx.getClass(), value);
return rootNode;
} else if (ctx.getClass().isArray()) {
if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(Array.class)) {
propHandlerSet(ex, ctx, Array.class, value);
} else {
//noinspection unchecked
Array.set(ctx, eval(ex, ctx, variableFactory, Integer.class), convert(value, getBaseComponentType(ctx.getClass())));
addAccessorNode(new ArrayAccessorNest(ex));
}
return rootNode;
} else {
throw new PropertyAccessException("cannot bind to collection property: " + new String(property) + ": not a recognized collection type: " + ctx.getClass(), expr, this.st);
}
} else if (MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING && hasPropertyHandler(ctx.getClass())) {
propHandlerSet(new String(property), ctx, ctx.getClass(), value);
return rootNode;
}
String tk = new String(property, 0, length);
if (hasSetListeners()) {
notifySetListeners(ctx, tk, variableFactory, value);
addAccessorNode(new Notify(tk));
}
Member member = getFieldOrWriteAccessor(ctx.getClass(), tk, value == null ? null : ingressType);
if (member instanceof Field) {
Field fld = (Field) member;
if (value != null && !fld.getType().isAssignableFrom(value.getClass())) {
if (!canConvert(fld.getType(), value.getClass())) {
throw new CompileException("cannot convert type: " + value.getClass() + ": to " + fld.getType(), this.expr, this.start);
}
fld.set(ctx, convert(value, fld.getType()));
addAccessorNode(new DynamicFieldAccessor(fld));
} else if (value == null && fld.getType().isPrimitive()) {
fld.set(ctx, PropertyTools.getPrimitiveInitialValue(fld.getType()));
addAccessorNode(new FieldAccessor(fld));
} else {
fld.set(ctx, value);
addAccessorNode(new FieldAccessor(fld));
}
} else if (member != null) {
Method meth = (Method) member;
if (value != null && !meth.getParameterTypes()[0].isAssignableFrom(value.getClass())) {
if (!canConvert(meth.getParameterTypes()[0], value.getClass())) {
throw new CompileException("cannot convert type: " + value.getClass() + ": to " + meth.getParameterTypes()[0], this.expr, this.start);
}
meth.invoke(ctx, convert(value, meth.getParameterTypes()[0]));
} else if (value == null && meth.getParameterTypes()[0].isPrimitive()) {
meth.invoke(ctx, PropertyTools.getPrimitiveInitialValue(meth.getParameterTypes()[0]));
} else {
meth.invoke(ctx, value);
}
addAccessorNode(new SetterAccessor(meth));
} else if (ctx instanceof Map) {
//noinspection unchecked
((Map) ctx).put(tk, value);
addAccessorNode(new MapAccessor(tk));
} else {
throw new PropertyAccessException("could not access property (" + tk + ") in: " + ingressType.getName(), this.expr, this.start);
}
} catch (InvocationTargetException e) {
throw new PropertyAccessException("could not access property: " + new String(property), this.expr, st, e);
} catch (IllegalAccessException e) {
throw new PropertyAccessException("could not access property: " + new String(property), this.expr, st, e);
} catch (IllegalArgumentException e) {
throw new PropertyAccessException("error binding property: " + new String(property) + " (value <<" + value + ">>::" + (value == null ? "null" : value.getClass().getCanonicalName()) + ")", this.expr, st, e);
}
return rootNode;
}
use of org.mvel2.compiler.Accessor in project mvel by mikebrock.
the class AbstractOptimizer method tryStaticAccess.
/**
* Try static access of the property, and return an instance of the Field, Method of Class if successful.
*
* @return - Field, Method or Class instance.
*/
protected Object tryStaticAccess() {
int begin = cursor;
try {
/**
* Try to resolve this *smartly* as a static class reference.
*
* This starts at the end of the token and starts to step backwards to figure out whether
* or not this may be a static class reference. We search for method calls simply by
* inspecting for ()'s. The first union area we come to where no brackets are present is our
* test-point for a class reference. If we find a class, we pass the reference to the
* property accessor along with trailing methods (if any).
*
*/
boolean meth = false;
// int end = start + length;
int last = end;
for (int i = end - 1; i > start; i--) {
switch(expr[i]) {
case '.':
if (!meth) {
try {
String test = new String(expr, start, (cursor = last) - start);
return Class.forName(test, true, pCtx != null ? pCtx.getParserConfiguration().getClassLoader() : currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
Class cls = Class.forName(new String(expr, start, i - start), true, pCtx != null ? pCtx.getParserConfiguration().getClassLoader() : currentThread().getContextClassLoader());
String name = new String(expr, i + 1, end - i - 1);
try {
return cls.getField(name);
} catch (NoSuchFieldException nfe) {
for (Method m : cls.getMethods()) {
if (name.equals(m.getName()))
return m;
}
return null;
}
}
}
meth = false;
last = i;
break;
case '}':
i--;
for (int d = 1; i > start && d != 0; i--) {
switch(expr[i]) {
case '}':
d++;
break;
case '{':
d--;
break;
case '"':
case '\'':
char s = expr[i];
while (i > start && (expr[i] != s && expr[i - 1] != '\\')) i--;
}
}
break;
case ')':
i--;
for (int d = 1; i > start && d != 0; i--) {
switch(expr[i]) {
case ')':
d++;
break;
case '(':
d--;
break;
case '"':
case '\'':
char s = expr[i];
while (i > start && (expr[i] != s && expr[i - 1] != '\\')) i--;
}
}
meth = true;
last = i++;
break;
case '\'':
while (--i > start) {
if (expr[i] == '\'' && expr[i - 1] != '\\') {
break;
}
}
break;
case '"':
while (--i > start) {
if (expr[i] == '"' && expr[i - 1] != '\\') {
break;
}
}
break;
}
}
} catch (Exception cnfe) {
cursor = begin;
}
return null;
}
use of org.mvel2.compiler.Accessor in project mvel by mikebrock.
the class OptimizerFactory method setDefaultOptimizer.
public static void setDefaultOptimizer(String name) {
try {
//noinspection unchecked
AccessorOptimizer ao = accessorCompilers.get(defaultOptimizer = name);
ao.init();
setThreadAccessorOptimizer(ao.getClass());
} catch (Exception e) {
throw new RuntimeException("unable to instantiate accessor compiler", e);
}
}
use of org.mvel2.compiler.Accessor in project mvel by mikebrock.
the class ASTNode method optimize.
private Object optimize(Object ctx, Object thisValue, VariableResolverFactory factory) {
if ((fields & DEOP) != 0) {
fields ^= DEOP;
}
AccessorOptimizer optimizer;
Object retVal = null;
if ((fields & NOJIT) != 0 || factory != null && factory.isResolveable(nameCache)) {
optimizer = getAccessorCompiler(SAFE_REFLECTIVE);
} else {
optimizer = getDefaultAccessorCompiler();
}
ParserContext pCtx;
if ((fields & PCTX_STORED) != 0) {
pCtx = (ParserContext) literal;
} else {
pCtx = new ParserContext(new ParserConfiguration(getInjectedImports(factory), null));
}
try {
pCtx.optimizationNotify();
setAccessor(optimizer.optimizeAccessor(pCtx, expr, start, offset, ctx, thisValue, factory, true, egressType));
} catch (OptimizationNotSupported ne) {
setAccessor((optimizer = getAccessorCompiler(SAFE_REFLECTIVE)).optimizeAccessor(pCtx, expr, start, offset, ctx, thisValue, factory, true, null));
}
if (accessor == null) {
return get(expr, start, offset, ctx, factory, thisValue);
}
if (retVal == null) {
retVal = optimizer.getResultOptPass();
}
if (egressType == null) {
egressType = optimizer.getEgressType();
}
return retVal;
}
Aggregations