Skip to content

Commit

Permalink
Merge pull request #18463 from rmuir/whitelist_cleanup
Browse files Browse the repository at this point in the history
painless: steps at definition cleanup
  • Loading branch information
rmuir committed May 20, 2016
2 parents 61f4015 + b156438 commit a2ff002
Show file tree
Hide file tree
Showing 80 changed files with 2,419 additions and 5,040 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
* Runs the analysis phase of compilation using the Painless AST.
*/
final class Analyzer {
static Variables analyze(final CompilerSettings settings, final Definition definition,
static Variables analyze(final CompilerSettings settings,
final Reserved shortcut, final SSource root) {
final Variables variables = new Variables(settings, definition, shortcut);
root.analyze(settings, definition, variables);
final Variables variables = new Variables(settings, shortcut);
root.analyze(variables);

return variables;
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ static byte[] compile(String name, String source, CompilerSettings settings) {
}

final Reserved reserved = new Reserved();
final SSource root = Walker.buildPainlessTree(source, reserved);
final Variables variables = Analyzer.analyze(settings, Definition.INSTANCE, reserved, root);
final SSource root = Walker.buildPainlessTree(source, reserved, settings);
final Variables variables = Analyzer.analyze(settings, reserved, root);

return Writer.write(settings, Definition.INSTANCE, name, source, variables, root);
return Writer.write(settings, name, source, variables, root);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,16 @@
*/
public final class CompilerSettings {

/**
* Constant to be used when specifying numeric overflow when compiling a script.
*/
public static final String NUMERIC_OVERFLOW = "numeric_overflow";

/**
* Constant to be used when specifying the maximum loop counter when compiling a script.
*/
public static final String MAX_LOOP_COUNTER = "max_loop_counter";

/**
* Whether or not to allow numeric values to overflow without exception.
*/
private boolean numericOverflow = true;

/**
* The maximum number of statements allowed to be run in a loop.
*/
private int maxLoopCounter = 10000;

/**
* Returns {@code true} if numeric operations should overflow, {@code false}
* if they should signal an exception.
* <p>
* If this value is {@code true} (default), then things behave like java:
* overflow for integer types can result in unexpected values / unexpected
* signs, and overflow for floating point types can result in infinite or
* {@code NaN} values.
*/
public final boolean getNumericOverflow() {
return numericOverflow;
}

/**
* Set {@code true} for numerics to overflow, false to deliver exceptions.
* @see #getNumericOverflow
*/
public final void setNumericOverflow(boolean allow) {
this.numericOverflow = allow;
}

/**
* Returns the value for the cumulative total number of statements that can be made in all loops
* in a script before an exception is thrown. This attempts to prevent infinite loops. Note if
Expand Down
171 changes: 15 additions & 156 deletions modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ public final class Def {
// TODO: Once Java has a factory for those in java.lang.invoke.MethodHandles, use it:

/** Helper class for isolating MethodHandles and methods to get the length of arrays
* (to emulate a "arraystore" byteoode using MethodHandles).
* (to emulate a "arraystore" bytecode using MethodHandles).
* This should really be a method in {@link MethodHandles} class!
*/
@SuppressWarnings("unused") // getArrayLength() methods are are actually used, javac just does not know :)
private static final class ArrayLengthHelper {
private static final Lookup PRIV_LOOKUP = MethodHandles.lookup();

Expand Down Expand Up @@ -134,17 +135,16 @@ static MethodHandle arrayLengthGetter(Class<?> arrayType) {
* @param receiverClass Class of the object to invoke the method on.
* @param name Name of the method.
* @param type Callsite signature. Need not match exactly, except the number of parameters.
* @param definition Whitelist to check.
* @return pointer to matching method to invoke. never returns null.
* @throws IllegalArgumentException if no matching whitelisted method was found.
*/
static MethodHandle lookupMethod(Class<?> receiverClass, String name, MethodType type, Definition definition) {
static MethodHandle lookupMethod(Class<?> receiverClass, String name, MethodType type) {
// we don't consider receiver an argument/counting towards arity
type = type.dropParameterTypes(0, 1);
Definition.MethodKey key = new Definition.MethodKey(name, type.parameterCount());
// check whitelist for matching method
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
RuntimeClass struct = definition.runtimeMap.get(clazz);
RuntimeClass struct = Definition.getRuntimeClass(clazz);

if (struct != null) {
Method method = struct.methods.get(key);
Expand All @@ -154,7 +154,7 @@ static MethodHandle lookupMethod(Class<?> receiverClass, String name, MethodType
}

for (final Class<?> iface : clazz.getInterfaces()) {
struct = definition.runtimeMap.get(iface);
struct = Definition.getRuntimeClass(iface);

if (struct != null) {
Method method = struct.methods.get(key);
Expand Down Expand Up @@ -192,14 +192,13 @@ static MethodHandle lookupMethod(Class<?> receiverClass, String name, MethodType
* <p>
* @param receiverClass Class of the object to retrieve the field from.
* @param name Name of the field.
* @param definition Whitelist to check.
* @return pointer to matching field. never returns null.
* @throws IllegalArgumentException if no matching whitelisted field was found.
*/
static MethodHandle lookupGetter(Class<?> receiverClass, String name, Definition definition) {
static MethodHandle lookupGetter(Class<?> receiverClass, String name) {
// first try whitelist
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
RuntimeClass struct = definition.runtimeMap.get(clazz);
RuntimeClass struct = Definition.getRuntimeClass(clazz);

if (struct != null) {
MethodHandle handle = struct.getters.get(name);
Expand All @@ -209,7 +208,7 @@ static MethodHandle lookupGetter(Class<?> receiverClass, String name, Definition
}

for (final Class<?> iface : clazz.getInterfaces()) {
struct = definition.runtimeMap.get(iface);
struct = Definition.getRuntimeClass(iface);

if (struct != null) {
MethodHandle handle = struct.getters.get(name);
Expand Down Expand Up @@ -263,14 +262,13 @@ static MethodHandle lookupGetter(Class<?> receiverClass, String name, Definition
* <p>
* @param receiverClass Class of the object to retrieve the field from.
* @param name Name of the field.
* @param definition Whitelist to check.
* @return pointer to matching field. never returns null.
* @throws IllegalArgumentException if no matching whitelisted field was found.
*/
static MethodHandle lookupSetter(Class<?> receiverClass, String name, Definition definition) {
static MethodHandle lookupSetter(Class<?> receiverClass, String name) {
// first try whitelist
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
RuntimeClass struct = definition.runtimeMap.get(clazz);
RuntimeClass struct = Definition.getRuntimeClass(clazz);

if (struct != null) {
MethodHandle handle = struct.setters.get(name);
Expand All @@ -280,7 +278,7 @@ static MethodHandle lookupSetter(Class<?> receiverClass, String name, Definition
}

for (final Class<?> iface : clazz.getInterfaces()) {
struct = definition.runtimeMap.get(iface);
struct = Definition.getRuntimeClass(iface);

if (struct != null) {
MethodHandle handle = struct.setters.get(name);
Expand Down Expand Up @@ -971,6 +969,10 @@ public static boolean gte(final Object left, final Object right) {

// Conversion methods for Def to primitive types.

public static boolean DefToboolean(final Object value) {
return (boolean)value;
}

public static byte DefTobyteImplicit(final Object value) {
return (byte)value;
}
Expand Down Expand Up @@ -1051,79 +1053,6 @@ public static double DefTodoubleImplicit(final Object value) {
}
}

public static Byte DefToByteImplicit(final Object value) {
return (Byte)value;
}

public static Short DefToShortImplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Byte) {
return ((Byte)value).shortValue();
} else {
return (Short)value;
}
}

public static Character DefToCharacterImplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Byte) {
return (char)(byte)value;
} else {
return (Character)value;
}
}

public static Integer DefToIntegerImplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Byte || value instanceof Short) {
return ((Number)value).intValue();
} else if (value instanceof Character) {
return (int)(char)value;
} else {
return (Integer)value;
}
}

public static Long DefToLongImplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Byte || value instanceof Short || value instanceof Integer) {
return ((Number)value).longValue();
} else if (value instanceof Character) {
return (long)(char)value;
} else {
return (Long)value;
}
}

public static Float DefToFloatImplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
return ((Number)value).floatValue();
} else if (value instanceof Character) {
return (float)(char)value;
} else {
return (Float)value;
}
}

public static Double DefToDoubleImplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Byte || value instanceof Short ||
value instanceof Integer || value instanceof Long || value instanceof Float) {
return ((Number)value).doubleValue();
} else if (value instanceof Character) {
return (double)(char)value;
} else {
return (Double)value;
}
}

public static byte DefTobyteExplicit(final Object value) {
if (value instanceof Character) {
return (byte)(char)value;
Expand Down Expand Up @@ -1179,74 +1108,4 @@ public static double DefTodoubleExplicit(final Object value) {
return ((Number)value).doubleValue();
}
}

public static Byte DefToByteExplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Character) {
return (byte)(char)value;
} else {
return ((Number)value).byteValue();
}
}

public static Short DefToShortExplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Character) {
return (short)(char)value;
} else {
return ((Number)value).shortValue();
}
}

public static Character DefToCharacterExplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Character) {
return ((Character)value);
} else {
return (char)((Number)value).intValue();
}
}

public static Integer DefToIntegerExplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Character) {
return (int)(char)value;
} else {
return ((Number)value).intValue();
}
}

public static Long DefToLongExplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Character) {
return (long)(char)value;
} else {
return ((Number)value).longValue();
}
}

public static Float DefToFloatExplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Character) {
return (float)(char)value;
} else {
return ((Number)value).floatValue();
}
}

public static Double DefToDoubleExplicit(final Object value) {
if (value == null) {
return null;
} else if (value instanceof Character) {
return (double)(char)value;
} else {
return ((Number)value).doubleValue();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ static boolean checkClass(Class<?> clazz, Object receiver) {
private static MethodHandle lookup(int flavor, Class<?> clazz, String name, MethodType type) {
switch(flavor) {
case METHOD_CALL:
return Def.lookupMethod(clazz, name, type, Definition.INSTANCE);
return Def.lookupMethod(clazz, name, type);
case LOAD:
return Def.lookupGetter(clazz, name, Definition.INSTANCE);
return Def.lookupGetter(clazz, name);
case STORE:
return Def.lookupSetter(clazz, name, Definition.INSTANCE);
return Def.lookupSetter(clazz, name);
case ARRAY_LOAD:
return Def.lookupArrayLoad(clazz);
case ARRAY_STORE:
Expand Down
Loading

0 comments on commit a2ff002

Please sign in to comment.