Remove the Definition instance passed around everywhere
This commit is contained in:
parent
91f4bba042
commit
4ffa92c7c1
|
@ -26,10 +26,10 @@ import org.elasticsearch.painless.node.SSource;
|
||||||
* Runs the analysis phase of compilation using the Painless AST.
|
* Runs the analysis phase of compilation using the Painless AST.
|
||||||
*/
|
*/
|
||||||
final class Analyzer {
|
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 Reserved shortcut, final SSource root) {
|
||||||
final Variables variables = new Variables(settings, definition, shortcut);
|
final Variables variables = new Variables(settings, shortcut);
|
||||||
root.analyze(settings, definition, variables);
|
root.analyze(settings, variables);
|
||||||
|
|
||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
*/
|
*/
|
||||||
public final class AnalyzerCaster {
|
public final class AnalyzerCaster {
|
||||||
|
|
||||||
public static Cast getLegalCast(final Definition definition,
|
public static Cast getLegalCast(final String location, final Type actual, final Type expected, final boolean explicit) {
|
||||||
final String location, final Type actual, final Type expected, final boolean explicit) {
|
|
||||||
final Cast cast = new Cast(actual, expected, explicit);
|
final Cast cast = new Cast(actual, expected, explicit);
|
||||||
|
|
||||||
if (actual.equals(expected)) {
|
if (actual.equals(expected)) {
|
||||||
|
@ -115,7 +114,7 @@ public final class AnalyzerCaster {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type promoteNumeric(final Definition definition, final Type from, final boolean decimal, final boolean primitive) {
|
public static Type promoteNumeric(final Type from, final boolean decimal, final boolean primitive) {
|
||||||
final Sort sort = from.sort;
|
final Sort sort = from.sort;
|
||||||
|
|
||||||
if (sort == Sort.DEF) {
|
if (sort == Sort.DEF) {
|
||||||
|
@ -136,8 +135,7 @@ public final class AnalyzerCaster {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type promoteNumeric(final Definition definition,
|
public static Type promoteNumeric(final Type from0, final Type from1, final boolean decimal, final boolean primitive) {
|
||||||
final Type from0, final Type from1, final boolean decimal, final boolean primitive) {
|
|
||||||
final Sort sort0 = from0.sort;
|
final Sort sort0 = from0.sort;
|
||||||
final Sort sort1 = from1.sort;
|
final Sort sort1 = from1.sort;
|
||||||
|
|
||||||
|
@ -171,7 +169,7 @@ public final class AnalyzerCaster {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type promoteAdd(final Definition definition, final Type from0, final Type from1) {
|
public static Type promoteAdd(final Type from0, final Type from1) {
|
||||||
final Sort sort0 = from0.sort;
|
final Sort sort0 = from0.sort;
|
||||||
final Sort sort1 = from1.sort;
|
final Sort sort1 = from1.sort;
|
||||||
|
|
||||||
|
@ -179,10 +177,10 @@ public final class AnalyzerCaster {
|
||||||
return Definition.stringType;
|
return Definition.stringType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return promoteNumeric(definition, from0, from1, true, true);
|
return promoteNumeric(from0, from1, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type promoteXor(final Definition definition, final Type from0, final Type from1) {
|
public static Type promoteXor(final Type from0, final Type from1) {
|
||||||
final Sort sort0 = from0.sort;
|
final Sort sort0 = from0.sort;
|
||||||
final Sort sort1 = from1.sort;
|
final Sort sort1 = from1.sort;
|
||||||
|
|
||||||
|
@ -190,10 +188,10 @@ public final class AnalyzerCaster {
|
||||||
return Definition.booleanType;
|
return Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return promoteNumeric(definition, from0, from1, false, true);
|
return promoteNumeric(from0, from1, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type promoteEquality(final Definition definition, final Type from0, final Type from1) {
|
public static Type promoteEquality(final Type from0, final Type from1) {
|
||||||
final Sort sort0 = from0.sort;
|
final Sort sort0 = from0.sort;
|
||||||
final Sort sort1 = from1.sort;
|
final Sort sort1 = from1.sort;
|
||||||
|
|
||||||
|
@ -208,13 +206,13 @@ public final class AnalyzerCaster {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sort0.numeric && sort1.numeric) {
|
if (sort0.numeric && sort1.numeric) {
|
||||||
return promoteNumeric(definition, from0, from1, true, primitive);
|
return promoteNumeric(from0, from1, true, primitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Definition.objectType;
|
return Definition.objectType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type promoteReference(final Definition definition, final Type from0, final Type from1) {
|
public static Type promoteReference(final Type from0, final Type from1) {
|
||||||
final Sort sort0 = from0.sort;
|
final Sort sort0 = from0.sort;
|
||||||
final Sort sort1 = from1.sort;
|
final Sort sort1 = from1.sort;
|
||||||
|
|
||||||
|
@ -228,15 +226,14 @@ public final class AnalyzerCaster {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sort0.numeric && sort1.numeric) {
|
if (sort0.numeric && sort1.numeric) {
|
||||||
return promoteNumeric(definition, from0, from1, true, true);
|
return promoteNumeric(from0, from1, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Definition.objectType;
|
return Definition.objectType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type promoteConditional(final Definition definition,
|
public static Type promoteConditional(final Type from0, final Type from1, final Object const0, final Object const1) {
|
||||||
final Type from0, final Type from1, final Object const0, final Object const1) {
|
|
||||||
if (from0.equals(from1)) {
|
if (from0.equals(from1)) {
|
||||||
return from0;
|
return from0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,9 +113,9 @@ final class Compiler {
|
||||||
|
|
||||||
final Reserved reserved = new Reserved();
|
final Reserved reserved = new Reserved();
|
||||||
final SSource root = Walker.buildPainlessTree(source, reserved);
|
final SSource root = Walker.buildPainlessTree(source, reserved);
|
||||||
final Variables variables = Analyzer.analyze(settings, Definition.INSTANCE, reserved, root);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -135,11 +135,10 @@ public final class Def {
|
||||||
* @param receiverClass Class of the object to invoke the method on.
|
* @param receiverClass Class of the object to invoke the method on.
|
||||||
* @param name Name of the method.
|
* @param name Name of the method.
|
||||||
* @param type Callsite signature. Need not match exactly, except the number of parameters.
|
* @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.
|
* @return pointer to matching method to invoke. never returns null.
|
||||||
* @throws IllegalArgumentException if no matching whitelisted method was found.
|
* @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
|
// we don't consider receiver an argument/counting towards arity
|
||||||
type = type.dropParameterTypes(0, 1);
|
type = type.dropParameterTypes(0, 1);
|
||||||
Definition.MethodKey key = new Definition.MethodKey(name, type.parameterCount());
|
Definition.MethodKey key = new Definition.MethodKey(name, type.parameterCount());
|
||||||
|
@ -193,11 +192,10 @@ public final class Def {
|
||||||
* <p>
|
* <p>
|
||||||
* @param receiverClass Class of the object to retrieve the field from.
|
* @param receiverClass Class of the object to retrieve the field from.
|
||||||
* @param name Name of the field.
|
* @param name Name of the field.
|
||||||
* @param definition Whitelist to check.
|
|
||||||
* @return pointer to matching field. never returns null.
|
* @return pointer to matching field. never returns null.
|
||||||
* @throws IllegalArgumentException if no matching whitelisted field was found.
|
* @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
|
// first try whitelist
|
||||||
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
|
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
|
||||||
RuntimeClass struct = Definition.getRuntimeClass(clazz);
|
RuntimeClass struct = Definition.getRuntimeClass(clazz);
|
||||||
|
@ -264,11 +262,10 @@ public final class Def {
|
||||||
* <p>
|
* <p>
|
||||||
* @param receiverClass Class of the object to retrieve the field from.
|
* @param receiverClass Class of the object to retrieve the field from.
|
||||||
* @param name Name of the field.
|
* @param name Name of the field.
|
||||||
* @param definition Whitelist to check.
|
|
||||||
* @return pointer to matching field. never returns null.
|
* @return pointer to matching field. never returns null.
|
||||||
* @throws IllegalArgumentException if no matching whitelisted field was found.
|
* @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
|
// first try whitelist
|
||||||
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
|
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
|
||||||
RuntimeClass struct = Definition.getRuntimeClass(clazz);
|
RuntimeClass struct = Definition.getRuntimeClass(clazz);
|
||||||
|
|
|
@ -94,11 +94,11 @@ public final class DefBootstrap {
|
||||||
private static MethodHandle lookup(int flavor, Class<?> clazz, String name, MethodType type) {
|
private static MethodHandle lookup(int flavor, Class<?> clazz, String name, MethodType type) {
|
||||||
switch(flavor) {
|
switch(flavor) {
|
||||||
case METHOD_CALL:
|
case METHOD_CALL:
|
||||||
return Def.lookupMethod(clazz, name, type, Definition.INSTANCE);
|
return Def.lookupMethod(clazz, name, type);
|
||||||
case LOAD:
|
case LOAD:
|
||||||
return Def.lookupGetter(clazz, name, Definition.INSTANCE);
|
return Def.lookupGetter(clazz, name);
|
||||||
case STORE:
|
case STORE:
|
||||||
return Def.lookupSetter(clazz, name, Definition.INSTANCE);
|
return Def.lookupSetter(clazz, name);
|
||||||
case ARRAY_LOAD:
|
case ARRAY_LOAD:
|
||||||
return Def.lookupArrayLoad(clazz);
|
return Def.lookupArrayLoad(clazz);
|
||||||
case ARRAY_STORE:
|
case ARRAY_STORE:
|
||||||
|
|
|
@ -40,11 +40,8 @@ public final class Definition {
|
||||||
|
|
||||||
private static final String DEFINITION_FILE = "definition.txt";
|
private static final String DEFINITION_FILE = "definition.txt";
|
||||||
|
|
||||||
/**
|
// The second construction is used to finalize all the variables, so there is no mistake of modification afterwards.
|
||||||
* The default language API to be used with Painless. The second construction is used
|
private static final Definition INSTANCE = new Definition(new Definition());
|
||||||
* to finalize all the variables, so there is no mistake of modification afterwards.
|
|
||||||
*/
|
|
||||||
public static final Definition INSTANCE = new Definition(new Definition());
|
|
||||||
|
|
||||||
/** Some native types as constants: */
|
/** Some native types as constants: */
|
||||||
public static final Type voidType = getType("void");
|
public static final Type voidType = getType("void");
|
||||||
|
|
|
@ -200,9 +200,7 @@ public final class MethodWriter extends GeneratorAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeBinaryInstruction(final Definition definition,
|
public void writeBinaryInstruction(final String location, final Type type, final Operation operation) {
|
||||||
final String location,
|
|
||||||
final Type type, final Operation operation) {
|
|
||||||
final Sort sort = type.sort;
|
final Sort sort = type.sort;
|
||||||
|
|
||||||
if ((sort == Sort.FLOAT || sort == Sort.DOUBLE) &&
|
if ((sort == Sort.FLOAT || sort == Sort.DOUBLE) &&
|
||||||
|
|
|
@ -86,14 +86,12 @@ public final class Variables {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Definition definition;
|
|
||||||
final Reserved reserved;
|
final Reserved reserved;
|
||||||
|
|
||||||
private final Deque<Integer> scopes = new ArrayDeque<>();
|
private final Deque<Integer> scopes = new ArrayDeque<>();
|
||||||
private final Deque<Variable> variables = new ArrayDeque<>();
|
private final Deque<Variable> variables = new ArrayDeque<>();
|
||||||
|
|
||||||
public Variables(final CompilerSettings settings, final Definition definition, final Reserved reserved) {
|
public Variables(final CompilerSettings settings, final Reserved reserved) {
|
||||||
this.definition = definition;
|
|
||||||
this.reserved = reserved;
|
this.reserved = reserved;
|
||||||
|
|
||||||
incrementScope();
|
incrementScope();
|
||||||
|
|
|
@ -38,15 +38,14 @@ import static org.elasticsearch.painless.WriterConstants.MAP_TYPE;
|
||||||
*/
|
*/
|
||||||
final class Writer {
|
final class Writer {
|
||||||
|
|
||||||
static byte[] write(final CompilerSettings settings, final Definition definition,
|
static byte[] write(final CompilerSettings settings,
|
||||||
String name, final String source, final Variables variables, final SSource root) {
|
String name, final String source, final Variables variables, final SSource root) {
|
||||||
final Writer writer = new Writer(settings, definition, name, source, variables, root);
|
final Writer writer = new Writer(settings, name, source, variables, root);
|
||||||
|
|
||||||
return writer.getBytes();
|
return writer.getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final CompilerSettings settings;
|
private final CompilerSettings settings;
|
||||||
private final Definition definition;
|
|
||||||
private final String scriptName;
|
private final String scriptName;
|
||||||
private final String source;
|
private final String source;
|
||||||
private final Variables variables;
|
private final Variables variables;
|
||||||
|
@ -55,10 +54,9 @@ final class Writer {
|
||||||
private final ClassWriter writer;
|
private final ClassWriter writer;
|
||||||
private final MethodWriter adapter;
|
private final MethodWriter adapter;
|
||||||
|
|
||||||
private Writer(final CompilerSettings settings, final Definition definition,
|
private Writer(final CompilerSettings settings,
|
||||||
String name, final String source, final Variables variables, final SSource root) {
|
String name, final String source, final Variables variables, final SSource root) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.definition = definition;
|
|
||||||
this.scriptName = name;
|
this.scriptName = name;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
|
@ -177,7 +175,7 @@ final class Writer {
|
||||||
adapter.visitVarInsn(Opcodes.ISTORE, loop.slot);
|
adapter.visitVarInsn(Opcodes.ISTORE, loop.slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
root.write(settings, definition, adapter);
|
root.write(settings, adapter);
|
||||||
adapter.endMethod();
|
adapter.endMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Definition.Cast;
|
import org.elasticsearch.painless.Definition.Cast;
|
||||||
import org.elasticsearch.painless.Definition.Type;
|
import org.elasticsearch.painless.Definition.Type;
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
|
@ -101,27 +100,27 @@ public abstract class AExpression extends ANode {
|
||||||
/**
|
/**
|
||||||
* Checks for errors and collects data for the writing phase.
|
* Checks for errors and collects data for the writing phase.
|
||||||
*/
|
*/
|
||||||
abstract void analyze(final CompilerSettings settings, final Definition definition, final Variables variables);
|
abstract void analyze(final CompilerSettings settings, final Variables variables);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes ASM based on the data collected during the analysis phase.
|
* Writes ASM based on the data collected during the analysis phase.
|
||||||
*/
|
*/
|
||||||
abstract void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter);
|
abstract void write(final CompilerSettings settings, final MethodWriter adapter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts {@link ECast} nodes into the tree for implicit casts. Also replaces
|
* Inserts {@link ECast} nodes into the tree for implicit casts. Also replaces
|
||||||
* nodes with the constant variable set to a non-null value with {@link EConstant}.
|
* nodes with the constant variable set to a non-null value with {@link EConstant}.
|
||||||
* @return The new child node for the parent node calling this method.
|
* @return The new child node for the parent node calling this method.
|
||||||
*/
|
*/
|
||||||
AExpression cast(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
AExpression cast(final CompilerSettings settings, final Variables variables) {
|
||||||
final Cast cast = AnalyzerCaster.getLegalCast(definition, location, actual, expected, explicit);
|
final Cast cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit);
|
||||||
|
|
||||||
if (cast == null) {
|
if (cast == null) {
|
||||||
if (constant == null || this instanceof EConstant) {
|
if (constant == null || this instanceof EConstant) {
|
||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
final EConstant econstant = new EConstant(line, location, constant);
|
final EConstant econstant = new EConstant(line, location, constant);
|
||||||
econstant.analyze(settings, definition, variables);
|
econstant.analyze(settings, variables);
|
||||||
|
|
||||||
if (!expected.equals(econstant.actual)) {
|
if (!expected.equals(econstant.actual)) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
|
@ -142,7 +141,7 @@ public abstract class AExpression extends ANode {
|
||||||
constant = AnalyzerCaster.constCast(location, constant, cast);
|
constant = AnalyzerCaster.constCast(location, constant, cast);
|
||||||
|
|
||||||
final EConstant econstant = new EConstant(line, location, constant);
|
final EConstant econstant = new EConstant(line, location, constant);
|
||||||
econstant.analyze(settings, definition, variables);
|
econstant.analyze(settings, variables);
|
||||||
|
|
||||||
if (!expected.equals(econstant.actual)) {
|
if (!expected.equals(econstant.actual)) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
|
@ -156,7 +155,7 @@ public abstract class AExpression extends ANode {
|
||||||
return ecast;
|
return ecast;
|
||||||
} else {
|
} else {
|
||||||
final EConstant econstant = new EConstant(line, location, constant);
|
final EConstant econstant = new EConstant(line, location, constant);
|
||||||
econstant.analyze(settings, definition, variables);
|
econstant.analyze(settings, variables);
|
||||||
|
|
||||||
if (!actual.equals(econstant.actual)) {
|
if (!actual.equals(econstant.actual)) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Definition.Type;
|
import org.elasticsearch.painless.Definition.Type;
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
@ -87,22 +86,22 @@ public abstract class ALink extends ANode {
|
||||||
* def or a shortcut is used. Otherwise, returns itself. This will be
|
* def or a shortcut is used. Otherwise, returns itself. This will be
|
||||||
* updated into the {@link EChain} node's list of links.
|
* updated into the {@link EChain} node's list of links.
|
||||||
*/
|
*/
|
||||||
abstract ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables);
|
abstract ALink analyze(final CompilerSettings settings, final Variables variables);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write values before a load/store occurs such as an array index.
|
* Write values before a load/store occurs such as an array index.
|
||||||
*/
|
*/
|
||||||
abstract void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter);
|
abstract void write(final CompilerSettings settings, final MethodWriter adapter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a load for the specific link type.
|
* Write a load for the specific link type.
|
||||||
*/
|
*/
|
||||||
abstract void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter);
|
abstract void load(final CompilerSettings settings, final MethodWriter adapter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a store for the specific link type.
|
* Write a store for the specific link type.
|
||||||
*/
|
*/
|
||||||
abstract void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter);
|
abstract void store(final CompilerSettings settings, final MethodWriter adapter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to copy link data from one to another during analysis in the case of replacement.
|
* Used to copy link data from one to another during analysis in the case of replacement.
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
@ -116,10 +115,10 @@ public abstract class AStatement extends ANode {
|
||||||
/**
|
/**
|
||||||
* Checks for errors and collects data for the writing phase.
|
* Checks for errors and collects data for the writing phase.
|
||||||
*/
|
*/
|
||||||
abstract void analyze(final CompilerSettings settings, final Definition definition, final Variables variables);
|
abstract void analyze(final CompilerSettings settings, final Variables variables);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes ASM based on the data collected during the analysis phase.
|
* Writes ASM based on the data collected during the analysis phase.
|
||||||
*/
|
*/
|
||||||
abstract void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter);
|
abstract void write(final CompilerSettings settings, final MethodWriter adapter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,39 +48,39 @@ public final class EBinary extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (operation == Operation.MUL) {
|
if (operation == Operation.MUL) {
|
||||||
analyzeMul(settings, definition, variables);
|
analyzeMul(settings, variables);
|
||||||
} else if (operation == Operation.DIV) {
|
} else if (operation == Operation.DIV) {
|
||||||
analyzeDiv(settings, definition, variables);
|
analyzeDiv(settings, variables);
|
||||||
} else if (operation == Operation.REM) {
|
} else if (operation == Operation.REM) {
|
||||||
analyzeRem(settings, definition, variables);
|
analyzeRem(settings, variables);
|
||||||
} else if (operation == Operation.ADD) {
|
} else if (operation == Operation.ADD) {
|
||||||
analyzeAdd(settings, definition, variables);
|
analyzeAdd(settings, variables);
|
||||||
} else if (operation == Operation.SUB) {
|
} else if (operation == Operation.SUB) {
|
||||||
analyzeSub(settings, definition, variables);
|
analyzeSub(settings, variables);
|
||||||
} else if (operation == Operation.LSH) {
|
} else if (operation == Operation.LSH) {
|
||||||
analyzeLSH(settings, definition, variables);
|
analyzeLSH(settings, variables);
|
||||||
} else if (operation == Operation.RSH) {
|
} else if (operation == Operation.RSH) {
|
||||||
analyzeRSH(settings, definition, variables);
|
analyzeRSH(settings, variables);
|
||||||
} else if (operation == Operation.USH) {
|
} else if (operation == Operation.USH) {
|
||||||
analyzeUSH(settings, definition, variables);
|
analyzeUSH(settings, variables);
|
||||||
} else if (operation == Operation.BWAND) {
|
} else if (operation == Operation.BWAND) {
|
||||||
analyzeBWAnd(settings, definition, variables);
|
analyzeBWAnd(settings, variables);
|
||||||
} else if (operation == Operation.XOR) {
|
} else if (operation == Operation.XOR) {
|
||||||
analyzeXor(settings, definition, variables);
|
analyzeXor(settings, variables);
|
||||||
} else if (operation == Operation.BWOR) {
|
} else if (operation == Operation.BWOR) {
|
||||||
analyzeBWOr(settings, definition, variables);
|
analyzeBWOr(settings, variables);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeMul(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeMul(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply multiply [*] to types " +
|
throw new ClassCastException(error("Cannot apply multiply [*] to types " +
|
||||||
|
@ -90,8 +90,8 @@ public final class EBinary extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -112,11 +112,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeDiv(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeDiv(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply divide [/] to types " +
|
throw new ClassCastException(error("Cannot apply divide [/] to types " +
|
||||||
|
@ -126,8 +126,8 @@ public final class EBinary extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -148,11 +148,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeRem(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeRem(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply remainder [%] to types " +
|
throw new ClassCastException(error("Cannot apply remainder [%] to types " +
|
||||||
|
@ -162,8 +162,8 @@ public final class EBinary extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -184,11 +184,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeAdd(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeAdd(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteAdd(definition, left.actual, right.actual);
|
final Type promote = AnalyzerCaster.promoteAdd(left.actual, right.actual);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply add [+] to types " +
|
throw new ClassCastException(error("Cannot apply add [+] to types " +
|
||||||
|
@ -214,8 +214,8 @@ public final class EBinary extends AExpression {
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
if (sort == Sort.INT) {
|
if (sort == Sort.INT) {
|
||||||
|
@ -236,11 +236,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeSub(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeSub(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply subtract [-] to types " +
|
throw new ClassCastException(error("Cannot apply subtract [-] to types " +
|
||||||
|
@ -250,8 +250,8 @@ public final class EBinary extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -272,11 +272,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeLSH(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeLSH(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply left shift [<<] to types " +
|
throw new ClassCastException(error("Cannot apply left shift [<<] to types " +
|
||||||
|
@ -287,8 +287,8 @@ public final class EBinary extends AExpression {
|
||||||
right.expected = Definition.intType;
|
right.expected = Definition.intType;
|
||||||
right.explicit = true;
|
right.explicit = true;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -305,11 +305,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeRSH(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeRSH(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply right shift [>>] to types " +
|
throw new ClassCastException(error("Cannot apply right shift [>>] to types " +
|
||||||
|
@ -320,8 +320,8 @@ public final class EBinary extends AExpression {
|
||||||
right.expected = Definition.intType;
|
right.expected = Definition.intType;
|
||||||
right.explicit = true;
|
right.explicit = true;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -338,11 +338,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeUSH(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeUSH(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply unsigned shift [>>>] to types " +
|
throw new ClassCastException(error("Cannot apply unsigned shift [>>>] to types " +
|
||||||
|
@ -353,8 +353,8 @@ public final class EBinary extends AExpression {
|
||||||
right.expected = Definition.intType;
|
right.expected = Definition.intType;
|
||||||
right.explicit = true;
|
right.explicit = true;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -371,11 +371,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeBWAnd(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeBWAnd(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, false, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply and [&] to types " +
|
throw new ClassCastException(error("Cannot apply and [&] to types " +
|
||||||
|
@ -385,8 +385,8 @@ public final class EBinary extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -403,11 +403,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeXor(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeXor(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteXor(definition, left.actual, right.actual);
|
final Type promote = AnalyzerCaster.promoteXor(left.actual, right.actual);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply xor [^] to types " +
|
throw new ClassCastException(error("Cannot apply xor [^] to types " +
|
||||||
|
@ -417,8 +417,8 @@ public final class EBinary extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -437,11 +437,11 @@ public final class EBinary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeBWOr(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeBWOr(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, false, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply or [|] to types " +
|
throw new ClassCastException(error("Cannot apply or [|] to types " +
|
||||||
|
@ -451,8 +451,8 @@ public final class EBinary extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -470,19 +470,19 @@ public final class EBinary extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (actual.sort == Sort.STRING && operation == Operation.ADD) {
|
if (actual.sort == Sort.STRING && operation == Operation.ADD) {
|
||||||
if (!cat) {
|
if (!cat) {
|
||||||
adapter.writeNewStrings();
|
adapter.writeNewStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
left.write(settings, definition, adapter);
|
left.write(settings, adapter);
|
||||||
|
|
||||||
if (!(left instanceof EBinary) || ((EBinary)left).operation != Operation.ADD || left.actual.sort != Sort.STRING) {
|
if (!(left instanceof EBinary) || ((EBinary)left).operation != Operation.ADD || left.actual.sort != Sort.STRING) {
|
||||||
adapter.writeAppendStrings(left.actual);
|
adapter.writeAppendStrings(left.actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
right.write(settings, definition, adapter);
|
right.write(settings, adapter);
|
||||||
|
|
||||||
if (!(right instanceof EBinary) || ((EBinary)right).operation != Operation.ADD || right.actual.sort != Sort.STRING) {
|
if (!(right instanceof EBinary) || ((EBinary)right).operation != Operation.ADD || right.actual.sort != Sort.STRING) {
|
||||||
adapter.writeAppendStrings(right.actual);
|
adapter.writeAppendStrings(right.actual);
|
||||||
|
@ -492,10 +492,10 @@ public final class EBinary extends AExpression {
|
||||||
adapter.writeToStrings();
|
adapter.writeToStrings();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
left.write(settings, definition, adapter);
|
left.write(settings, adapter);
|
||||||
right.write(settings, definition, adapter);
|
right.write(settings, adapter);
|
||||||
|
|
||||||
adapter.writeBinaryInstruction(definition, location, actual, operation);
|
adapter.writeBinaryInstruction(location, actual, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.writeBranch(tru, fals);
|
adapter.writeBranch(tru, fals);
|
||||||
|
|
|
@ -44,14 +44,14 @@ public final class EBool extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
left.expected = Definition.booleanType;
|
left.expected = Definition.booleanType;
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
|
|
||||||
right.expected = Definition.booleanType;
|
right.expected = Definition.booleanType;
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
if (operation == Operation.AND) {
|
if (operation == Operation.AND) {
|
||||||
|
@ -67,7 +67,7 @@ public final class EBool extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (tru != null || fals != null) {
|
if (tru != null || fals != null) {
|
||||||
if (operation == Operation.AND) {
|
if (operation == Operation.AND) {
|
||||||
final Label localfals = fals == null ? new Label() : fals;
|
final Label localfals = fals == null ? new Label() : fals;
|
||||||
|
@ -76,8 +76,8 @@ public final class EBool extends AExpression {
|
||||||
right.tru = tru;
|
right.tru = tru;
|
||||||
right.fals = fals;
|
right.fals = fals;
|
||||||
|
|
||||||
left.write(settings, definition, adapter);
|
left.write(settings, adapter);
|
||||||
right.write(settings, definition, adapter);
|
right.write(settings, adapter);
|
||||||
|
|
||||||
if (fals == null) {
|
if (fals == null) {
|
||||||
adapter.mark(localfals);
|
adapter.mark(localfals);
|
||||||
|
@ -89,8 +89,8 @@ public final class EBool extends AExpression {
|
||||||
right.tru = tru;
|
right.tru = tru;
|
||||||
right.fals = fals;
|
right.fals = fals;
|
||||||
|
|
||||||
left.write(settings, definition, adapter);
|
left.write(settings, adapter);
|
||||||
right.write(settings, definition, adapter);
|
right.write(settings, adapter);
|
||||||
|
|
||||||
if (tru == null) {
|
if (tru == null) {
|
||||||
adapter.mark(localtru);
|
adapter.mark(localtru);
|
||||||
|
@ -106,8 +106,8 @@ public final class EBool extends AExpression {
|
||||||
left.fals = localfals;
|
left.fals = localfals;
|
||||||
right.fals = localfals;
|
right.fals = localfals;
|
||||||
|
|
||||||
left.write(settings, definition, adapter);
|
left.write(settings, adapter);
|
||||||
right.write(settings, definition, adapter);
|
right.write(settings, adapter);
|
||||||
|
|
||||||
adapter.push(true);
|
adapter.push(true);
|
||||||
adapter.goTo(end);
|
adapter.goTo(end);
|
||||||
|
@ -122,8 +122,8 @@ public final class EBool extends AExpression {
|
||||||
left.tru = localtru;
|
left.tru = localtru;
|
||||||
right.fals = localfals;
|
right.fals = localfals;
|
||||||
|
|
||||||
left.write(settings, definition, adapter);
|
left.write(settings, adapter);
|
||||||
right.write(settings, definition, adapter);
|
right.write(settings, adapter);
|
||||||
|
|
||||||
adapter.mark(localtru);
|
adapter.mark(localtru);
|
||||||
adapter.push(true);
|
adapter.push(true);
|
||||||
|
|
|
@ -36,12 +36,12 @@ public final class EBoolean extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalArgumentException(error("Illegal tree structure."));
|
throw new IllegalArgumentException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Definition.Cast;
|
import org.elasticsearch.painless.Definition.Cast;
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
@ -46,13 +45,13 @@ final class ECast extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
child.write(settings, definition, adapter);
|
child.write(settings, adapter);
|
||||||
adapter.writeCast(cast);
|
adapter.writeCast(cast);
|
||||||
adapter.writeBranch(tru, fals);
|
adapter.writeBranch(tru, fals);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,20 +59,20 @@ public final class EChain extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
analyzeLinks(settings, definition, variables);
|
analyzeLinks(settings, variables);
|
||||||
analyzeIncrDecr();
|
analyzeIncrDecr();
|
||||||
|
|
||||||
if (operation != null) {
|
if (operation != null) {
|
||||||
analyzeCompound(settings, definition, variables);
|
analyzeCompound(settings, variables);
|
||||||
} else if (expression != null) {
|
} else if (expression != null) {
|
||||||
analyzeWrite(settings, definition, variables);
|
analyzeWrite(settings, variables);
|
||||||
} else {
|
} else {
|
||||||
analyzeRead();
|
analyzeRead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeLinks(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeLinks(final CompilerSettings settings, final Variables variables) {
|
||||||
ALink previous = null;
|
ALink previous = null;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ public final class EChain extends AExpression {
|
||||||
current.store = expression != null || pre || post;
|
current.store = expression != null || pre || post;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ALink analyzed = current.analyze(settings, definition, variables);
|
final ALink analyzed = current.analyze(settings, variables);
|
||||||
|
|
||||||
if (analyzed == null) {
|
if (analyzed == null) {
|
||||||
links.remove(index);
|
links.remove(index);
|
||||||
|
@ -153,33 +153,33 @@ public final class EChain extends AExpression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeCompound(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeCompound(final CompilerSettings settings, final Variables variables) {
|
||||||
final ALink last = links.get(links.size() - 1);
|
final ALink last = links.get(links.size() - 1);
|
||||||
|
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
|
|
||||||
if (operation == Operation.MUL) {
|
if (operation == Operation.MUL) {
|
||||||
promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true);
|
promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true);
|
||||||
} else if (operation == Operation.DIV) {
|
} else if (operation == Operation.DIV) {
|
||||||
promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true);
|
promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true);
|
||||||
} else if (operation == Operation.REM) {
|
} else if (operation == Operation.REM) {
|
||||||
promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true);
|
promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true);
|
||||||
} else if (operation == Operation.ADD) {
|
} else if (operation == Operation.ADD) {
|
||||||
promote = AnalyzerCaster.promoteAdd(definition, last.after, expression.actual);
|
promote = AnalyzerCaster.promoteAdd(last.after, expression.actual);
|
||||||
} else if (operation == Operation.SUB) {
|
} else if (operation == Operation.SUB) {
|
||||||
promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true);
|
promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true);
|
||||||
} else if (operation == Operation.LSH) {
|
} else if (operation == Operation.LSH) {
|
||||||
promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true);
|
promote = AnalyzerCaster.promoteNumeric(last.after, false, true);
|
||||||
} else if (operation == Operation.RSH) {
|
} else if (operation == Operation.RSH) {
|
||||||
promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true);
|
promote = AnalyzerCaster.promoteNumeric(last.after, false, true);
|
||||||
} else if (operation == Operation.USH) {
|
} else if (operation == Operation.USH) {
|
||||||
promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true);
|
promote = AnalyzerCaster.promoteNumeric(last.after, false, true);
|
||||||
} else if (operation == Operation.BWAND) {
|
} else if (operation == Operation.BWAND) {
|
||||||
promote = AnalyzerCaster.promoteXor(definition, last.after, expression.actual);
|
promote = AnalyzerCaster.promoteXor(last.after, expression.actual);
|
||||||
} else if (operation == Operation.XOR) {
|
} else if (operation == Operation.XOR) {
|
||||||
promote = AnalyzerCaster.promoteXor(definition, last.after, expression.actual);
|
promote = AnalyzerCaster.promoteXor(last.after, expression.actual);
|
||||||
} else if (operation == Operation.BWOR) {
|
} else if (operation == Operation.BWOR) {
|
||||||
promote = AnalyzerCaster.promoteXor(definition, last.after, expression.actual);
|
promote = AnalyzerCaster.promoteXor(last.after, expression.actual);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
@ -205,30 +205,30 @@ public final class EChain extends AExpression {
|
||||||
expression.expected = promote;
|
expression.expected = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
expression = expression.cast(settings, definition, variables);
|
expression = expression.cast(settings, variables);
|
||||||
|
|
||||||
there = AnalyzerCaster.getLegalCast(definition, location, last.after, promote, false);
|
there = AnalyzerCaster.getLegalCast(location, last.after, promote, false);
|
||||||
back = AnalyzerCaster.getLegalCast(definition, location, promote, last.after, true);
|
back = AnalyzerCaster.getLegalCast(location, promote, last.after, true);
|
||||||
|
|
||||||
this.statement = true;
|
this.statement = true;
|
||||||
this.actual = read ? last.after : Definition.voidType;
|
this.actual = read ? last.after : Definition.voidType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeWrite(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeWrite(final CompilerSettings settings, final Variables variables) {
|
||||||
final ALink last = links.get(links.size() - 1);
|
final ALink last = links.get(links.size() - 1);
|
||||||
|
|
||||||
// If the store node is a DEF node, we remove the cast to DEF from the expression
|
// If the store node is a DEF node, we remove the cast to DEF from the expression
|
||||||
// and promote the real type to it:
|
// and promote the real type to it:
|
||||||
if (last instanceof IDefLink) {
|
if (last instanceof IDefLink) {
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
last.after = expression.expected = expression.actual;
|
last.after = expression.expected = expression.actual;
|
||||||
} else {
|
} else {
|
||||||
// otherwise we adapt the type of the expression to the store type
|
// otherwise we adapt the type of the expression to the store type
|
||||||
expression.expected = last.after;
|
expression.expected = last.after;
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
expression = expression.cast(settings, definition, variables);
|
expression = expression.cast(settings, variables);
|
||||||
|
|
||||||
this.statement = true;
|
this.statement = true;
|
||||||
this.actual = read ? last.after : Definition.voidType;
|
this.actual = read ? last.after : Definition.voidType;
|
||||||
|
@ -248,7 +248,7 @@ public final class EChain extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings,final MethodWriter adapter) {
|
||||||
if (cat) {
|
if (cat) {
|
||||||
adapter.writeNewStrings();
|
adapter.writeNewStrings();
|
||||||
}
|
}
|
||||||
|
@ -256,15 +256,15 @@ public final class EChain extends AExpression {
|
||||||
final ALink last = links.get(links.size() - 1);
|
final ALink last = links.get(links.size() - 1);
|
||||||
|
|
||||||
for (final ALink link : links) {
|
for (final ALink link : links) {
|
||||||
link.write(settings, definition, adapter);
|
link.write(settings, adapter);
|
||||||
|
|
||||||
if (link == last && link.store) {
|
if (link == last && link.store) {
|
||||||
if (cat) {
|
if (cat) {
|
||||||
adapter.writeDup(link.size, 1);
|
adapter.writeDup(link.size, 1);
|
||||||
link.load(settings, definition, adapter);
|
link.load(settings, adapter);
|
||||||
adapter.writeAppendStrings(link.after);
|
adapter.writeAppendStrings(link.after);
|
||||||
|
|
||||||
expression.write(settings, definition, adapter);
|
expression.write(settings, adapter);
|
||||||
|
|
||||||
if (!(expression instanceof EBinary) ||
|
if (!(expression instanceof EBinary) ||
|
||||||
((EBinary)expression).operation != Operation.ADD || expression.actual.sort != Sort.STRING) {
|
((EBinary)expression).operation != Operation.ADD || expression.actual.sort != Sort.STRING) {
|
||||||
|
@ -278,18 +278,18 @@ public final class EChain extends AExpression {
|
||||||
adapter.writeDup(link.after.sort.size, link.size);
|
adapter.writeDup(link.after.sort.size, link.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
link.store(settings, definition, adapter);
|
link.store(settings, adapter);
|
||||||
} else if (operation != null) {
|
} else if (operation != null) {
|
||||||
adapter.writeDup(link.size, 0);
|
adapter.writeDup(link.size, 0);
|
||||||
link.load(settings, definition, adapter);
|
link.load(settings, adapter);
|
||||||
|
|
||||||
if (link.load && post) {
|
if (link.load && post) {
|
||||||
adapter.writeDup(link.after.sort.size, link.size);
|
adapter.writeDup(link.after.sort.size, link.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.writeCast(there);
|
adapter.writeCast(there);
|
||||||
expression.write(settings, definition, adapter);
|
expression.write(settings, adapter);
|
||||||
adapter.writeBinaryInstruction(definition, location, promote, operation);
|
adapter.writeBinaryInstruction(location, promote, operation);
|
||||||
|
|
||||||
adapter.writeCast(back);
|
adapter.writeCast(back);
|
||||||
|
|
||||||
|
@ -297,18 +297,18 @@ public final class EChain extends AExpression {
|
||||||
adapter.writeDup(link.after.sort.size, link.size);
|
adapter.writeDup(link.after.sort.size, link.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
link.store(settings, definition, adapter);
|
link.store(settings, adapter);
|
||||||
} else {
|
} else {
|
||||||
expression.write(settings, definition, adapter);
|
expression.write(settings, adapter);
|
||||||
|
|
||||||
if (link.load) {
|
if (link.load) {
|
||||||
adapter.writeDup(link.after.sort.size, link.size);
|
adapter.writeDup(link.after.sort.size, link.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
link.store(settings, definition, adapter);
|
link.store(settings, adapter);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
link.load(settings, definition, adapter);
|
link.load(settings, adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,33 +54,33 @@ public final class EComp extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (operation == Operation.EQ) {
|
if (operation == Operation.EQ) {
|
||||||
analyzeEq(settings, definition, variables);
|
analyzeEq(settings, variables);
|
||||||
} else if (operation == Operation.EQR) {
|
} else if (operation == Operation.EQR) {
|
||||||
analyzeEqR(settings, definition, variables);
|
analyzeEqR(settings, variables);
|
||||||
} else if (operation == Operation.NE) {
|
} else if (operation == Operation.NE) {
|
||||||
analyzeNE(settings, definition, variables);
|
analyzeNE(settings, variables);
|
||||||
} else if (operation == Operation.NER) {
|
} else if (operation == Operation.NER) {
|
||||||
analyzeNER(settings, definition, variables);
|
analyzeNER(settings, variables);
|
||||||
} else if (operation == Operation.GTE) {
|
} else if (operation == Operation.GTE) {
|
||||||
analyzeGTE(settings, definition, variables);
|
analyzeGTE(settings, variables);
|
||||||
} else if (operation == Operation.GT) {
|
} else if (operation == Operation.GT) {
|
||||||
analyzeGT(settings, definition, variables);
|
analyzeGT(settings, variables);
|
||||||
} else if (operation == Operation.LTE) {
|
} else if (operation == Operation.LTE) {
|
||||||
analyzeLTE(settings, definition, variables);
|
analyzeLTE(settings, variables);
|
||||||
} else if (operation == Operation.LT) {
|
} else if (operation == Operation.LT) {
|
||||||
analyzeLT(settings, definition, variables);
|
analyzeLT(settings, variables);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeEq(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeEq(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteEquality(definition, left.actual, right.actual);
|
final Type promote = AnalyzerCaster.promoteEquality(left.actual, right.actual);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply equals [==] to types " +
|
throw new ClassCastException(error("Cannot apply equals [==] to types " +
|
||||||
|
@ -90,8 +90,8 @@ public final class EComp extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.isNull && right.isNull) {
|
if (left.isNull && right.isNull) {
|
||||||
throw new IllegalArgumentException(error("Extraneous comparison of null constants."));
|
throw new IllegalArgumentException(error("Extraneous comparison of null constants."));
|
||||||
|
@ -122,11 +122,11 @@ public final class EComp extends AExpression {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeEqR(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeEqR(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteReference(definition, left.actual, right.actual);
|
final Type promote = AnalyzerCaster.promoteReference(left.actual, right.actual);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply reference equals [===] to types " +
|
throw new ClassCastException(error("Cannot apply reference equals [===] to types " +
|
||||||
|
@ -136,8 +136,8 @@ public final class EComp extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.isNull && right.isNull) {
|
if (left.isNull && right.isNull) {
|
||||||
throw new IllegalArgumentException(error("Extraneous comparison of null constants."));
|
throw new IllegalArgumentException(error("Extraneous comparison of null constants."));
|
||||||
|
@ -164,11 +164,11 @@ public final class EComp extends AExpression {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeNE(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeNE(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteEquality(definition, left.actual, right.actual);
|
final Type promote = AnalyzerCaster.promoteEquality(left.actual, right.actual);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply not equals [!=] to types " +
|
throw new ClassCastException(error("Cannot apply not equals [!=] to types " +
|
||||||
|
@ -178,8 +178,8 @@ public final class EComp extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.isNull && right.isNull) {
|
if (left.isNull && right.isNull) {
|
||||||
throw new IllegalArgumentException(error("Extraneous comparison of null constants."));
|
throw new IllegalArgumentException(error("Extraneous comparison of null constants."));
|
||||||
|
@ -210,11 +210,11 @@ public final class EComp extends AExpression {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeNER(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeNER(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteReference(definition, left.actual, right.actual);
|
final Type promote = AnalyzerCaster.promoteReference(left.actual, right.actual);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply reference not equals [!==] to types " +
|
throw new ClassCastException(error("Cannot apply reference not equals [!==] to types " +
|
||||||
|
@ -224,8 +224,8 @@ public final class EComp extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.isNull && right.isNull) {
|
if (left.isNull && right.isNull) {
|
||||||
throw new IllegalArgumentException(error("Extraneous comparison of null constants."));
|
throw new IllegalArgumentException(error("Extraneous comparison of null constants."));
|
||||||
|
@ -252,11 +252,11 @@ public final class EComp extends AExpression {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeGTE(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeGTE(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply greater than or equals [>=] to types " +
|
throw new ClassCastException(error("Cannot apply greater than or equals [>=] to types " +
|
||||||
|
@ -266,8 +266,8 @@ public final class EComp extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -288,11 +288,11 @@ public final class EComp extends AExpression {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeGT(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeGT(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply greater than [>] to types " +
|
throw new ClassCastException(error("Cannot apply greater than [>] to types " +
|
||||||
|
@ -302,8 +302,8 @@ public final class EComp extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -324,11 +324,11 @@ public final class EComp extends AExpression {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeLTE(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeLTE(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply less than or equals [<=] to types " +
|
throw new ClassCastException(error("Cannot apply less than or equals [<=] to types " +
|
||||||
|
@ -338,8 +338,8 @@ public final class EComp extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -360,11 +360,11 @@ public final class EComp extends AExpression {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeLT(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
private void analyzeLT(final CompilerSettings settings, final Variables variables) {
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply less than [>=] to types " +
|
throw new ClassCastException(error("Cannot apply less than [>=] to types " +
|
||||||
|
@ -374,8 +374,8 @@ public final class EComp extends AExpression {
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
|
|
||||||
if (left.constant != null && right.constant != null) {
|
if (left.constant != null && right.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -397,15 +397,15 @@ public final class EComp extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
final boolean branch = tru != null || fals != null;
|
final boolean branch = tru != null || fals != null;
|
||||||
final org.objectweb.asm.Type rtype = right.actual.type;
|
final org.objectweb.asm.Type rtype = right.actual.type;
|
||||||
final Sort rsort = right.actual.sort;
|
final Sort rsort = right.actual.sort;
|
||||||
|
|
||||||
left.write(settings, definition, adapter);
|
left.write(settings, adapter);
|
||||||
|
|
||||||
if (!right.isNull) {
|
if (!right.isNull) {
|
||||||
right.write(settings, definition, adapter);
|
right.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Label jump = tru != null ? tru : fals != null ? fals : new Label();
|
final Label jump = tru != null ? tru : fals != null ? fals : new Label();
|
||||||
|
|
|
@ -46,10 +46,10 @@ public final class EConditional extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
condition.expected = Definition.booleanType;
|
condition.expected = Definition.booleanType;
|
||||||
condition.analyze(settings, definition, variables);
|
condition.analyze(settings, variables);
|
||||||
condition = condition.cast(settings, definition, variables);
|
condition = condition.cast(settings, variables);
|
||||||
|
|
||||||
if (condition.constant != null) {
|
if (condition.constant != null) {
|
||||||
throw new IllegalArgumentException(error("Extraneous conditional statement."));
|
throw new IllegalArgumentException(error("Extraneous conditional statement."));
|
||||||
|
@ -61,23 +61,23 @@ public final class EConditional extends AExpression {
|
||||||
right.explicit = explicit;
|
right.explicit = explicit;
|
||||||
actual = expected;
|
actual = expected;
|
||||||
|
|
||||||
left.analyze(settings, definition, variables);
|
left.analyze(settings, variables);
|
||||||
right.analyze(settings, definition, variables);
|
right.analyze(settings, variables);
|
||||||
|
|
||||||
if (expected == null) {
|
if (expected == null) {
|
||||||
final Type promote = AnalyzerCaster.promoteConditional(definition, left.actual, right.actual, left.constant, right.constant);
|
final Type promote = AnalyzerCaster.promoteConditional(left.actual, right.actual, left.constant, right.constant);
|
||||||
|
|
||||||
left.expected = promote;
|
left.expected = promote;
|
||||||
right.expected = promote;
|
right.expected = promote;
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
left = left.cast(settings, definition, variables);
|
left = left.cast(settings, variables);
|
||||||
right = right.cast(settings, definition, variables);
|
right = right.cast(settings, variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
final Label localfals = new Label();
|
final Label localfals = new Label();
|
||||||
final Label end = new Label();
|
final Label end = new Label();
|
||||||
|
|
||||||
|
@ -85,11 +85,11 @@ public final class EConditional extends AExpression {
|
||||||
left.tru = right.tru = tru;
|
left.tru = right.tru = tru;
|
||||||
left.fals = right.fals = fals;
|
left.fals = right.fals = fals;
|
||||||
|
|
||||||
condition.write(settings, definition, adapter);
|
condition.write(settings, adapter);
|
||||||
left.write(settings, definition, adapter);
|
left.write(settings, adapter);
|
||||||
adapter.goTo(end);
|
adapter.goTo(end);
|
||||||
adapter.mark(localfals);
|
adapter.mark(localfals);
|
||||||
right.write(settings, definition, adapter);
|
right.write(settings, adapter);
|
||||||
adapter.mark(end);
|
adapter.mark(end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ final class EConstant extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (constant instanceof String) {
|
if (constant instanceof String) {
|
||||||
actual = Definition.stringType;
|
actual = Definition.stringType;
|
||||||
} else if (constant instanceof Double) {
|
} else if (constant instanceof Double) {
|
||||||
|
@ -63,7 +63,7 @@ final class EConstant extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
final Sort sort = actual.sort;
|
final Sort sort = actual.sort;
|
||||||
|
|
||||||
switch (sort) {
|
switch (sort) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public final class EDecimal extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (value.endsWith("f") || value.endsWith("F")) {
|
if (value.endsWith("f") || value.endsWith("F")) {
|
||||||
try {
|
try {
|
||||||
constant = Float.parseFloat(value.substring(0, value.length() - 1));
|
constant = Float.parseFloat(value.substring(0, value.length() - 1));
|
||||||
|
@ -57,7 +57,7 @@ public final class EDecimal extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalArgumentException(error("Illegal tree structure."));
|
throw new IllegalArgumentException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public final class EExplicit extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
try {
|
try {
|
||||||
actual = Definition.getType(this.type);
|
actual = Definition.getType(this.type);
|
||||||
} catch (final IllegalArgumentException exception) {
|
} catch (final IllegalArgumentException exception) {
|
||||||
|
@ -49,19 +49,19 @@ public final class EExplicit extends AExpression {
|
||||||
|
|
||||||
child.expected = actual;
|
child.expected = actual;
|
||||||
child.explicit = true;
|
child.explicit = true;
|
||||||
child.analyze(settings, definition, variables);
|
child.analyze(settings, variables);
|
||||||
child = child.cast(settings, definition, variables);
|
child = child.cast(settings, variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalArgumentException(error("Illegal tree structure."));
|
throw new IllegalArgumentException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
||||||
AExpression cast(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
AExpression cast(final CompilerSettings settings, final Variables variables) {
|
||||||
child.expected = expected;
|
child.expected = expected;
|
||||||
child.explicit = explicit;
|
child.explicit = explicit;
|
||||||
|
|
||||||
return child.cast(settings, definition, variables);
|
return child.cast(settings, variables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public final class ENull extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
isNull = true;
|
isNull = true;
|
||||||
|
|
||||||
if (expected != null) {
|
if (expected != null) {
|
||||||
|
@ -50,7 +50,7 @@ public final class ENull extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.visitInsn(Opcodes.ACONST_NULL);
|
adapter.visitInsn(Opcodes.ACONST_NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public final class ENumeric extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (value.endsWith("d") || value.endsWith("D")) {
|
if (value.endsWith("d") || value.endsWith("D")) {
|
||||||
if (radix != 10) {
|
if (radix != 10) {
|
||||||
throw new IllegalStateException(error("Invalid tree structure."));
|
throw new IllegalStateException(error("Invalid tree structure."));
|
||||||
|
@ -96,7 +96,7 @@ public final class ENumeric extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalArgumentException(error("Illegal tree structure."));
|
throw new IllegalArgumentException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,24 +48,24 @@ public final class EUnary extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (operation == Operation.NOT) {
|
if (operation == Operation.NOT) {
|
||||||
analyzeNot(settings, definition, variables);
|
analyzeNot(settings, variables);
|
||||||
} else if (operation == Operation.BWNOT) {
|
} else if (operation == Operation.BWNOT) {
|
||||||
analyzeBWNot(settings, definition, variables);
|
analyzeBWNot(settings, variables);
|
||||||
} else if (operation == Operation.ADD) {
|
} else if (operation == Operation.ADD) {
|
||||||
analyzerAdd(settings, definition, variables);
|
analyzerAdd(settings, variables);
|
||||||
} else if (operation == Operation.SUB) {
|
} else if (operation == Operation.SUB) {
|
||||||
analyzerSub(settings, definition, variables);
|
analyzerSub(settings, variables);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void analyzeNot(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyzeNot(final CompilerSettings settings, final Variables variables) {
|
||||||
child.expected = Definition.booleanType;
|
child.expected = Definition.booleanType;
|
||||||
child.analyze(settings, definition, variables);
|
child.analyze(settings, variables);
|
||||||
child = child.cast(settings, definition, variables);
|
child = child.cast(settings, variables);
|
||||||
|
|
||||||
if (child.constant != null) {
|
if (child.constant != null) {
|
||||||
constant = !(boolean)child.constant;
|
constant = !(boolean)child.constant;
|
||||||
|
@ -74,17 +74,17 @@ public final class EUnary extends AExpression {
|
||||||
actual = Definition.booleanType;
|
actual = Definition.booleanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void analyzeBWNot(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyzeBWNot(final CompilerSettings settings, final Variables variables) {
|
||||||
child.analyze(settings, definition, variables);
|
child.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, false, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(child.actual, false, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply not [~] to type [" + child.actual.name + "]."));
|
throw new ClassCastException(error("Cannot apply not [~] to type [" + child.actual.name + "]."));
|
||||||
}
|
}
|
||||||
|
|
||||||
child.expected = promote;
|
child.expected = promote;
|
||||||
child = child.cast(settings, definition, variables);
|
child = child.cast(settings, variables);
|
||||||
|
|
||||||
if (child.constant != null) {
|
if (child.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -101,17 +101,17 @@ public final class EUnary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
void analyzerAdd(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyzerAdd(final CompilerSettings settings, final Variables variables) {
|
||||||
child.analyze(settings, definition, variables);
|
child.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(child.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply positive [+] to type [" + child.actual.name + "]."));
|
throw new ClassCastException(error("Cannot apply positive [+] to type [" + child.actual.name + "]."));
|
||||||
}
|
}
|
||||||
|
|
||||||
child.expected = promote;
|
child.expected = promote;
|
||||||
child = child.cast(settings, definition, variables);
|
child = child.cast(settings, variables);
|
||||||
|
|
||||||
if (child.constant != null) {
|
if (child.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -132,17 +132,17 @@ public final class EUnary extends AExpression {
|
||||||
actual = promote;
|
actual = promote;
|
||||||
}
|
}
|
||||||
|
|
||||||
void analyzerSub(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyzerSub(final CompilerSettings settings, final Variables variables) {
|
||||||
child.analyze(settings, definition, variables);
|
child.analyze(settings, variables);
|
||||||
|
|
||||||
final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, true, true);
|
final Type promote = AnalyzerCaster.promoteNumeric(child.actual, true, true);
|
||||||
|
|
||||||
if (promote == null) {
|
if (promote == null) {
|
||||||
throw new ClassCastException(error("Cannot apply negative [-] to type [" + child.actual.name + "]."));
|
throw new ClassCastException(error("Cannot apply negative [-] to type [" + child.actual.name + "]."));
|
||||||
}
|
}
|
||||||
|
|
||||||
child.expected = promote;
|
child.expected = promote;
|
||||||
child = child.cast(settings, definition, variables);
|
child = child.cast(settings, variables);
|
||||||
|
|
||||||
if (child.constant != null) {
|
if (child.constant != null) {
|
||||||
final Sort sort = promote.sort;
|
final Sort sort = promote.sort;
|
||||||
|
@ -164,14 +164,14 @@ public final class EUnary extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (operation == Operation.NOT) {
|
if (operation == Operation.NOT) {
|
||||||
if (tru == null && fals == null) {
|
if (tru == null && fals == null) {
|
||||||
final Label localfals = new Label();
|
final Label localfals = new Label();
|
||||||
final Label end = new Label();
|
final Label end = new Label();
|
||||||
|
|
||||||
child.fals = localfals;
|
child.fals = localfals;
|
||||||
child.write(settings, definition, adapter);
|
child.write(settings, adapter);
|
||||||
|
|
||||||
adapter.push(false);
|
adapter.push(false);
|
||||||
adapter.goTo(end);
|
adapter.goTo(end);
|
||||||
|
@ -181,13 +181,13 @@ public final class EUnary extends AExpression {
|
||||||
} else {
|
} else {
|
||||||
child.tru = fals;
|
child.tru = fals;
|
||||||
child.fals = tru;
|
child.fals = tru;
|
||||||
child.write(settings, definition, adapter);
|
child.write(settings, adapter);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final org.objectweb.asm.Type type = actual.type;
|
final org.objectweb.asm.Type type = actual.type;
|
||||||
final Sort sort = actual.sort;
|
final Sort sort = actual.sort;
|
||||||
|
|
||||||
child.write(settings, definition, adapter);
|
child.write(settings, adapter);
|
||||||
|
|
||||||
if (operation == Operation.BWNOT) {
|
if (operation == Operation.BWNOT) {
|
||||||
if (sort == Sort.DEF) {
|
if (sort == Sort.DEF) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public final class LArrayLength extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if ("length".equals(value)) {
|
if ("length".equals(value)) {
|
||||||
if (!load) {
|
if (!load) {
|
||||||
throw new IllegalArgumentException(error("Must read array field [length]."));
|
throw new IllegalArgumentException(error("Must read array field [length]."));
|
||||||
|
@ -55,17 +55,17 @@ public final class LArrayLength extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.arrayLength();
|
adapter.arrayLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public final class LBrace extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (before == null) {
|
if (before == null) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
@ -51,35 +51,35 @@ public final class LBrace extends ALink {
|
||||||
|
|
||||||
if (sort == Sort.ARRAY) {
|
if (sort == Sort.ARRAY) {
|
||||||
index.expected = Definition.intType;
|
index.expected = Definition.intType;
|
||||||
index.analyze(settings, definition, variables);
|
index.analyze(settings, variables);
|
||||||
index = index.cast(settings, definition, variables);
|
index = index.cast(settings, variables);
|
||||||
|
|
||||||
after = Definition.getType(before.struct, before.dimensions - 1);
|
after = Definition.getType(before.struct, before.dimensions - 1);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
} else if (sort == Sort.DEF) {
|
} else if (sort == Sort.DEF) {
|
||||||
return new LDefArray(line, location, index).copy(this).analyze(settings, definition, variables);
|
return new LDefArray(line, location, index).copy(this).analyze(settings, variables);
|
||||||
} else if (Map.class.isAssignableFrom(before.clazz)) {
|
} else if (Map.class.isAssignableFrom(before.clazz)) {
|
||||||
return new LMapShortcut(line, location, index).copy(this).analyze(settings, definition, variables);
|
return new LMapShortcut(line, location, index).copy(this).analyze(settings, variables);
|
||||||
} else if (List.class.isAssignableFrom(before.clazz)) {
|
} else if (List.class.isAssignableFrom(before.clazz)) {
|
||||||
return new LListShortcut(line, location, index).copy(this).analyze(settings, definition, variables);
|
return new LListShortcut(line, location, index).copy(this).analyze(settings, variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException(error("Illegal array access on type [" + before.name + "]."));
|
throw new IllegalArgumentException(error("Illegal array access on type [" + before.name + "]."));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
index.write(settings, definition, adapter);
|
index.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.arrayLoad(after.type);
|
adapter.arrayLoad(after.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.arrayStore(after.type);
|
adapter.arrayStore(after.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public final class LCall extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (before == null) {
|
if (before == null) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
} else if (before.sort == Definition.Sort.ARRAY) {
|
} else if (before.sort == Definition.Sort.ARRAY) {
|
||||||
|
@ -64,8 +64,8 @@ public final class LCall extends ALink {
|
||||||
final AExpression expression = arguments.get(argument);
|
final AExpression expression = arguments.get(argument);
|
||||||
|
|
||||||
expression.expected = method.arguments.get(argument);
|
expression.expected = method.arguments.get(argument);
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
arguments.set(argument, expression.cast(settings, definition, variables));
|
arguments.set(argument, expression.cast(settings, variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
statement = true;
|
statement = true;
|
||||||
|
@ -76,7 +76,7 @@ public final class LCall extends ALink {
|
||||||
final ALink link = new LDefCall(line, location, name, arguments);
|
final ALink link = new LDefCall(line, location, name, arguments);
|
||||||
link.copy(this);
|
link.copy(this);
|
||||||
|
|
||||||
return link.analyze(settings, definition, variables);
|
return link.analyze(settings, variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException(error("Unknown call [" + name + "] with [" + arguments.size() +
|
throw new IllegalArgumentException(error("Unknown call [" + name + "] with [" + arguments.size() +
|
||||||
|
@ -84,14 +84,14 @@ public final class LCall extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
for (final AExpression argument : arguments) {
|
for (final AExpression argument : arguments) {
|
||||||
argument.write(settings, definition, adapter);
|
argument.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isStatic(method.reflect.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(method.reflect.getModifiers())) {
|
||||||
|
@ -108,7 +108,7 @@ public final class LCall extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public final class LCast extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (before == null) {
|
if (before == null) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
} else if (store) {
|
} else if (store) {
|
||||||
|
@ -55,23 +55,23 @@ public final class LCast extends ALink {
|
||||||
throw new IllegalArgumentException(error("Not a type [" + type + "]."));
|
throw new IllegalArgumentException(error("Not a type [" + type + "]."));
|
||||||
}
|
}
|
||||||
|
|
||||||
cast = AnalyzerCaster.getLegalCast(definition, location, before, after, true);
|
cast = AnalyzerCaster.getLegalCast(location, before, after, true);
|
||||||
|
|
||||||
return cast != null ? this : null;
|
return cast != null ? this : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.writeCast(cast);
|
adapter.writeCast(cast);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,10 @@ final class LDefArray extends ALink implements IDefLink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
index.analyze(settings, definition, variables);
|
index.analyze(settings, variables);
|
||||||
index.expected = index.actual;
|
index.expected = index.actual;
|
||||||
index = index.cast(settings, definition, variables);
|
index = index.cast(settings, variables);
|
||||||
|
|
||||||
after = Definition.defType;
|
after = Definition.defType;
|
||||||
|
|
||||||
|
@ -53,18 +53,18 @@ final class LDefArray extends ALink implements IDefLink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
index.write(settings, definition, adapter);
|
index.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type, index.actual.type);
|
final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type, index.actual.type);
|
||||||
adapter.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_LOAD);
|
adapter.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_LOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type,
|
final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type,
|
||||||
index.actual.type, after.type);
|
index.actual.type, after.type);
|
||||||
adapter.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_STORE);
|
adapter.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_STORE);
|
||||||
|
|
|
@ -45,13 +45,13 @@ final class LDefCall extends ALink implements IDefLink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
for (int argument = 0; argument < arguments.size(); ++argument) {
|
for (int argument = 0; argument < arguments.size(); ++argument) {
|
||||||
final AExpression expression = arguments.get(argument);
|
final AExpression expression = arguments.get(argument);
|
||||||
|
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
expression.expected = expression.actual;
|
expression.expected = expression.actual;
|
||||||
arguments.set(argument, expression.cast(settings, definition, variables));
|
arguments.set(argument, expression.cast(settings, variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
statement = true;
|
statement = true;
|
||||||
|
@ -61,12 +61,12 @@ final class LDefCall extends ALink implements IDefLink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
final StringBuilder signature = new StringBuilder();
|
final StringBuilder signature = new StringBuilder();
|
||||||
|
|
||||||
signature.append('(');
|
signature.append('(');
|
||||||
|
@ -77,7 +77,7 @@ final class LDefCall extends ALink implements IDefLink {
|
||||||
// it can avoid some unnecessary boxing etc.
|
// it can avoid some unnecessary boxing etc.
|
||||||
for (final AExpression argument : arguments) {
|
for (final AExpression argument : arguments) {
|
||||||
signature.append(argument.actual.type.getDescriptor());
|
signature.append(argument.actual.type.getDescriptor());
|
||||||
argument.write(settings, definition, adapter);
|
argument.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
signature.append(')');
|
signature.append(')');
|
||||||
|
@ -88,7 +88,7 @@ final class LDefCall extends ALink implements IDefLink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,25 +43,25 @@ final class LDefField extends ALink implements IDefLink {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
after = Definition.defType;
|
after = Definition.defType;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type);
|
final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type);
|
||||||
adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.LOAD);
|
adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.LOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type, after.type);
|
final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type, after.type);
|
||||||
adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.STORE);
|
adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.STORE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public final class LField extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(CompilerSettings settings, Definition definition, Variables variables) {
|
ALink analyze(CompilerSettings settings, Variables variables) {
|
||||||
if (before == null) {
|
if (before == null) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,9 @@ public final class LField extends ALink {
|
||||||
final Sort sort = before.sort;
|
final Sort sort = before.sort;
|
||||||
|
|
||||||
if (sort == Sort.ARRAY) {
|
if (sort == Sort.ARRAY) {
|
||||||
return new LArrayLength(line, location, value).copy(this).analyze(settings, definition, variables);
|
return new LArrayLength(line, location, value).copy(this).analyze(settings, variables);
|
||||||
} else if (sort == Sort.DEF) {
|
} else if (sort == Sort.DEF) {
|
||||||
return new LDefField(line, location, value).copy(this).analyze(settings, definition, variables);
|
return new LDefField(line, location, value).copy(this).analyze(settings, variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Struct struct = before.struct;
|
final Struct struct = before.struct;
|
||||||
|
@ -80,17 +80,17 @@ public final class LField extends ALink {
|
||||||
Character.toUpperCase(value.charAt(0)) + value.substring(1), 1));
|
Character.toUpperCase(value.charAt(0)) + value.substring(1), 1));
|
||||||
|
|
||||||
if (shortcut) {
|
if (shortcut) {
|
||||||
return new LShortcut(line, location, value).copy(this).analyze(settings, definition, variables);
|
return new LShortcut(line, location, value).copy(this).analyze(settings, variables);
|
||||||
} else {
|
} else {
|
||||||
final EConstant index = new EConstant(line, location, value);
|
final EConstant index = new EConstant(line, location, value);
|
||||||
index.analyze(settings, definition, variables);
|
index.analyze(settings, variables);
|
||||||
|
|
||||||
if (Map.class.isAssignableFrom(before.clazz)) {
|
if (Map.class.isAssignableFrom(before.clazz)) {
|
||||||
return new LMapShortcut(line, location, index).copy(this).analyze(settings, definition, variables);
|
return new LMapShortcut(line, location, index).copy(this).analyze(settings, variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (List.class.isAssignableFrom(before.clazz)) {
|
if (List.class.isAssignableFrom(before.clazz)) {
|
||||||
return new LListShortcut(line, location, index).copy(this).analyze(settings, definition, variables);
|
return new LListShortcut(line, location, index).copy(this).analyze(settings, variables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,12 +99,12 @@ public final class LField extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) {
|
||||||
adapter.getStatic(field.owner.type, field.reflect.getName(), field.type.type);
|
adapter.getStatic(field.owner.type, field.reflect.getName(), field.type.type);
|
||||||
} else {
|
} else {
|
||||||
|
@ -113,7 +113,7 @@ public final class LField extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) {
|
||||||
adapter.putStatic(field.owner.type, field.reflect.getName(), field.type.type);
|
adapter.putStatic(field.owner.type, field.reflect.getName(), field.type.type);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -42,7 +42,7 @@ final class LListShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
getter = before.struct.methods.get(new Definition.MethodKey("get", 1));
|
getter = before.struct.methods.get(new Definition.MethodKey("get", 1));
|
||||||
setter = before.struct.methods.get(new Definition.MethodKey("set", 2));
|
setter = before.struct.methods.get(new Definition.MethodKey("set", 2));
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ final class LListShortcut extends ALink {
|
||||||
|
|
||||||
if ((load || store) && (!load || getter != null) && (!store || setter != null)) {
|
if ((load || store) && (!load || getter != null) && (!store || setter != null)) {
|
||||||
index.expected = Definition.intType;
|
index.expected = Definition.intType;
|
||||||
index.analyze(settings, definition, variables);
|
index.analyze(settings, variables);
|
||||||
index = index.cast(settings, definition, variables);
|
index = index.cast(settings, variables);
|
||||||
|
|
||||||
after = setter != null ? setter.arguments.get(1) : getter.rtn;
|
after = setter != null ? setter.arguments.get(1) : getter.rtn;
|
||||||
} else {
|
} else {
|
||||||
|
@ -74,12 +74,12 @@ final class LListShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
index.write(settings, definition, adapter);
|
index.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) {
|
if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) {
|
||||||
adapter.invokeInterface(getter.owner.type, getter.method);
|
adapter.invokeInterface(getter.owner.type, getter.method);
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,7 +92,7 @@ final class LListShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) {
|
if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) {
|
||||||
adapter.invokeInterface(setter.owner.type, setter.method);
|
adapter.invokeInterface(setter.owner.type, setter.method);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -42,7 +42,7 @@ final class LMapShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
getter = before.struct.methods.get(new Definition.MethodKey("get", 1));
|
getter = before.struct.methods.get(new Definition.MethodKey("get", 1));
|
||||||
setter = before.struct.methods.get(new Definition.MethodKey("put", 2));
|
setter = before.struct.methods.get(new Definition.MethodKey("put", 2));
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ final class LMapShortcut extends ALink {
|
||||||
|
|
||||||
if ((load || store) && (!load || getter != null) && (!store || setter != null)) {
|
if ((load || store) && (!load || getter != null) && (!store || setter != null)) {
|
||||||
index.expected = setter != null ? setter.arguments.get(0) : getter.arguments.get(0);
|
index.expected = setter != null ? setter.arguments.get(0) : getter.arguments.get(0);
|
||||||
index.analyze(settings, definition, variables);
|
index.analyze(settings, variables);
|
||||||
index = index.cast(settings, definition, variables);
|
index = index.cast(settings, variables);
|
||||||
|
|
||||||
after = setter != null ? setter.arguments.get(1) : getter.rtn;
|
after = setter != null ? setter.arguments.get(1) : getter.rtn;
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,12 +73,12 @@ final class LMapShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
index.write(settings, definition, adapter);
|
index.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) {
|
if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) {
|
||||||
adapter.invokeInterface(getter.owner.type, getter.method);
|
adapter.invokeInterface(getter.owner.type, getter.method);
|
||||||
} else {
|
} else {
|
||||||
|
@ -91,7 +91,7 @@ final class LMapShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) {
|
if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) {
|
||||||
adapter.invokeInterface(setter.owner.type, setter.method);
|
adapter.invokeInterface(setter.owner.type, setter.method);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -43,7 +43,7 @@ public final class LNewArray extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (before != null) {
|
if (before != null) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
} else if (store) {
|
} else if (store) {
|
||||||
|
@ -64,8 +64,8 @@ public final class LNewArray extends ALink {
|
||||||
final AExpression expression = arguments.get(argument);
|
final AExpression expression = arguments.get(argument);
|
||||||
|
|
||||||
expression.expected = Definition.intType;
|
expression.expected = Definition.intType;
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
arguments.set(argument, expression.cast(settings, definition, variables));
|
arguments.set(argument, expression.cast(settings, variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
after = Definition.getType(type.struct, arguments.size());
|
after = Definition.getType(type.struct, arguments.size());
|
||||||
|
@ -74,14 +74,14 @@ public final class LNewArray extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
for (final AExpression argument : arguments) {
|
for (final AExpression argument : arguments) {
|
||||||
argument.write(settings, definition, adapter);
|
argument.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments.size() > 1) {
|
if (arguments.size() > 1) {
|
||||||
|
@ -92,7 +92,7 @@ public final class LNewArray extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public final class LNewObj extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (before != null) {
|
if (before != null) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure"));
|
throw new IllegalStateException(error("Illegal tree structure"));
|
||||||
} else if (store) {
|
} else if (store) {
|
||||||
|
@ -78,8 +78,8 @@ public final class LNewObj extends ALink {
|
||||||
final AExpression expression = arguments.get(argument);
|
final AExpression expression = arguments.get(argument);
|
||||||
|
|
||||||
expression.expected = types[argument];
|
expression.expected = types[argument];
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
arguments.set(argument, expression.cast(settings, definition, variables));
|
arguments.set(argument, expression.cast(settings, variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
statement = true;
|
statement = true;
|
||||||
|
@ -92,12 +92,12 @@ public final class LNewObj extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.newInstance(after.type);
|
adapter.newInstance(after.type);
|
||||||
|
|
||||||
if (load) {
|
if (load) {
|
||||||
|
@ -105,14 +105,14 @@ public final class LNewObj extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final AExpression argument : arguments) {
|
for (final AExpression argument : arguments) {
|
||||||
argument.write(settings, definition, adapter);
|
argument.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.invokeConstructor(constructor.owner.type, constructor.method);
|
adapter.invokeConstructor(constructor.owner.type, constructor.method);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ final class LShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
final Struct struct = before.struct;
|
final Struct struct = before.struct;
|
||||||
|
|
||||||
getter = struct.methods.get(new Definition.MethodKey("get" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0));
|
getter = struct.methods.get(new Definition.MethodKey("get" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0));
|
||||||
|
@ -74,12 +74,12 @@ final class LShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) {
|
if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) {
|
||||||
adapter.invokeInterface(getter.owner.type, getter.method);
|
adapter.invokeInterface(getter.owner.type, getter.method);
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,7 +92,7 @@ final class LShortcut extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) {
|
if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) {
|
||||||
adapter.invokeInterface(setter.owner.type, setter.method);
|
adapter.invokeInterface(setter.owner.type, setter.method);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -36,7 +36,7 @@ public final class LString extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (before != null) {
|
if (before != null) {
|
||||||
throw new IllegalStateException("Illegal tree structure.");
|
throw new IllegalStateException("Illegal tree structure.");
|
||||||
} else if (store) {
|
} else if (store) {
|
||||||
|
@ -51,17 +51,17 @@ public final class LString extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.push(string);
|
adapter.push(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public final class LVariable extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
ALink analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (before != null) {
|
if (before != null) {
|
||||||
throw new IllegalStateException(error("Illegal tree structure."));
|
throw new IllegalStateException(error("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
@ -74,17 +74,17 @@ public final class LVariable extends ALink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void load(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.visitVarInsn(after.type.getOpcode(Opcodes.ILOAD), slot);
|
adapter.visitVarInsn(after.type.getOpcode(Opcodes.ILOAD), slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void store(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
adapter.visitVarInsn(after.type.getOpcode(Opcodes.ISTORE), slot);
|
adapter.visitVarInsn(after.type.getOpcode(Opcodes.ISTORE), slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ public final class SBlock extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
final AStatement last = statements.get(statements.size() - 1);
|
final AStatement last = statements.get(statements.size() - 1);
|
||||||
|
|
||||||
for (final AStatement statement : statements) {
|
for (final AStatement statement : statements) {
|
||||||
|
@ -53,7 +52,7 @@ public final class SBlock extends AStatement {
|
||||||
statement.lastSource = lastSource && statement == last;
|
statement.lastSource = lastSource && statement == last;
|
||||||
statement.lastLoop = (beginLoop || lastLoop) && statement == last;
|
statement.lastLoop = (beginLoop || lastLoop) && statement == last;
|
||||||
|
|
||||||
statement.analyze(settings, definition, variables);
|
statement.analyze(settings, variables);
|
||||||
|
|
||||||
methodEscape = statement.methodEscape;
|
methodEscape = statement.methodEscape;
|
||||||
loopEscape = statement.loopEscape;
|
loopEscape = statement.loopEscape;
|
||||||
|
@ -65,11 +64,11 @@ public final class SBlock extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
for (final AStatement statement : statements) {
|
for (final AStatement statement : statements) {
|
||||||
statement.continu = continu;
|
statement.continu = continu;
|
||||||
statement.brake = brake;
|
statement.brake = brake;
|
||||||
statement.write(settings, definition, adapter);
|
statement.write(settings, adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ public final class SBreak extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (!inLoop) {
|
if (!inLoop) {
|
||||||
throw new IllegalArgumentException(error("Break statement outside of a loop."));
|
throw new IllegalArgumentException(error("Break statement outside of a loop."));
|
||||||
}
|
}
|
||||||
|
@ -46,7 +45,7 @@ public final class SBreak extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
adapter.goTo(brake);
|
adapter.goTo(brake);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ public final class SContinue extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
if (!inLoop) {
|
if (!inLoop) {
|
||||||
throw new IllegalArgumentException(error("Continue statement outside of a loop."));
|
throw new IllegalArgumentException(error("Continue statement outside of a loop."));
|
||||||
}
|
}
|
||||||
|
@ -49,7 +48,7 @@ public final class SContinue extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
adapter.goTo(continu);
|
adapter.goTo(continu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
|
||||||
|
@ -41,18 +40,18 @@ public final class SDeclBlock extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
for (final SDeclaration declaration : declarations) {
|
for (final SDeclaration declaration : declarations) {
|
||||||
declaration.analyze(settings, definition, variables);
|
declaration.analyze(settings, variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
statementCount = declarations.size();
|
statementCount = declarations.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
for (final SDeclaration declaration : declarations) {
|
for (final SDeclaration declaration : declarations) {
|
||||||
declaration.write(settings, definition, adapter);
|
declaration.write(settings, adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Definition.Sort;
|
import org.elasticsearch.painless.Definition.Sort;
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.elasticsearch.painless.Variables.Variable;
|
import org.elasticsearch.painless.Variables.Variable;
|
||||||
|
@ -47,18 +46,18 @@ public final class SDeclaration extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
variable = variables.addVariable(location, type, name, false, false);
|
variable = variables.addVariable(location, type, name, false, false);
|
||||||
|
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
expression.expected = variable.type;
|
expression.expected = variable.type;
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
expression = expression.cast(settings, definition, variables);
|
expression = expression.cast(settings, variables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
final org.objectweb.asm.Type type = variable.type.type;
|
final org.objectweb.asm.Type type = variable.type.type;
|
||||||
final Sort sort = variable.type.sort;
|
final Sort sort = variable.type.sort;
|
||||||
|
@ -66,7 +65,7 @@ public final class SDeclaration extends AStatement {
|
||||||
final boolean initialize = expression == null;
|
final boolean initialize = expression == null;
|
||||||
|
|
||||||
if (!initialize) {
|
if (!initialize) {
|
||||||
expression.write(settings, definition, adapter);
|
expression.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sort) {
|
switch (sort) {
|
||||||
|
|
|
@ -41,21 +41,21 @@ public final class SDo extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
variables.incrementScope();
|
variables.incrementScope();
|
||||||
|
|
||||||
block.beginLoop = true;
|
block.beginLoop = true;
|
||||||
block.inLoop = true;
|
block.inLoop = true;
|
||||||
|
|
||||||
block.analyze(settings, definition, variables);
|
block.analyze(settings, variables);
|
||||||
|
|
||||||
if (block.loopEscape && !block.anyContinue) {
|
if (block.loopEscape && !block.anyContinue) {
|
||||||
throw new IllegalArgumentException(error("Extraneous do while loop."));
|
throw new IllegalArgumentException(error("Extraneous do while loop."));
|
||||||
}
|
}
|
||||||
|
|
||||||
condition.expected = Definition.booleanType;
|
condition.expected = Definition.booleanType;
|
||||||
condition.analyze(settings, definition, variables);
|
condition.analyze(settings, variables);
|
||||||
condition = condition.cast(settings, definition, variables);
|
condition = condition.cast(settings, variables);
|
||||||
|
|
||||||
if (condition.constant != null) {
|
if (condition.constant != null) {
|
||||||
final boolean continuous = (boolean)condition.constant;
|
final boolean continuous = (boolean)condition.constant;
|
||||||
|
@ -80,7 +80,7 @@ public final class SDo extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
final Label start = new Label();
|
final Label start = new Label();
|
||||||
final Label begin = new Label();
|
final Label begin = new Label();
|
||||||
|
@ -90,12 +90,12 @@ public final class SDo extends AStatement {
|
||||||
|
|
||||||
block.continu = begin;
|
block.continu = begin;
|
||||||
block.brake = end;
|
block.brake = end;
|
||||||
block.write(settings, definition, adapter);
|
block.write(settings, adapter);
|
||||||
|
|
||||||
adapter.mark(begin);
|
adapter.mark(begin);
|
||||||
|
|
||||||
condition.fals = end;
|
condition.fals = end;
|
||||||
condition.write(settings, definition, adapter);
|
condition.write(settings, adapter);
|
||||||
|
|
||||||
adapter.writeLoopCounter(loopCounterSlot, Math.max(1, block.statementCount));
|
adapter.writeLoopCounter(loopCounterSlot, Math.max(1, block.statementCount));
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,9 @@ public final class SExpression extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
expression.read = lastSource;
|
expression.read = lastSource;
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
|
|
||||||
if (!lastSource && !expression.statement) {
|
if (!lastSource && !expression.statement) {
|
||||||
throw new IllegalArgumentException(error("Not a statement."));
|
throw new IllegalArgumentException(error("Not a statement."));
|
||||||
|
@ -50,7 +50,7 @@ public final class SExpression extends AStatement {
|
||||||
final boolean rtn = lastSource && expression.actual.sort != Sort.VOID;
|
final boolean rtn = lastSource && expression.actual.sort != Sort.VOID;
|
||||||
|
|
||||||
expression.expected = rtn ? Definition.objectType : expression.actual;
|
expression.expected = rtn ? Definition.objectType : expression.actual;
|
||||||
expression = expression.cast(settings, definition, variables);
|
expression = expression.cast(settings, variables);
|
||||||
|
|
||||||
methodEscape = rtn;
|
methodEscape = rtn;
|
||||||
loopEscape = rtn;
|
loopEscape = rtn;
|
||||||
|
@ -59,9 +59,9 @@ public final class SExpression extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
expression.write(settings, definition, adapter);
|
expression.write(settings, adapter);
|
||||||
|
|
||||||
if (methodEscape) {
|
if (methodEscape) {
|
||||||
adapter.returnValue();
|
adapter.returnValue();
|
||||||
|
|
|
@ -46,19 +46,19 @@ public final class SFor extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
variables.incrementScope();
|
variables.incrementScope();
|
||||||
|
|
||||||
boolean continuous = false;
|
boolean continuous = false;
|
||||||
|
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
if (initializer instanceof SDeclBlock) {
|
if (initializer instanceof SDeclBlock) {
|
||||||
((SDeclBlock)initializer).analyze(settings, definition, variables);
|
((SDeclBlock)initializer).analyze(settings, variables);
|
||||||
} else if (initializer instanceof AExpression) {
|
} else if (initializer instanceof AExpression) {
|
||||||
final AExpression initializer = (AExpression)this.initializer;
|
final AExpression initializer = (AExpression)this.initializer;
|
||||||
|
|
||||||
initializer.read = false;
|
initializer.read = false;
|
||||||
initializer.analyze(settings, definition, variables);
|
initializer.analyze(settings, variables);
|
||||||
|
|
||||||
if (!initializer.statement) {
|
if (!initializer.statement) {
|
||||||
throw new IllegalArgumentException(initializer.error("Not a statement."));
|
throw new IllegalArgumentException(initializer.error("Not a statement."));
|
||||||
|
@ -71,8 +71,8 @@ public final class SFor extends AStatement {
|
||||||
if (condition != null) {
|
if (condition != null) {
|
||||||
|
|
||||||
condition.expected = Definition.booleanType;
|
condition.expected = Definition.booleanType;
|
||||||
condition.analyze(settings, definition, variables);
|
condition.analyze(settings, variables);
|
||||||
condition = condition.cast(settings, definition, variables);
|
condition = condition.cast(settings, variables);
|
||||||
|
|
||||||
if (condition.constant != null) {
|
if (condition.constant != null) {
|
||||||
continuous = (boolean)condition.constant;
|
continuous = (boolean)condition.constant;
|
||||||
|
@ -91,7 +91,7 @@ public final class SFor extends AStatement {
|
||||||
|
|
||||||
if (afterthought != null) {
|
if (afterthought != null) {
|
||||||
afterthought.read = false;
|
afterthought.read = false;
|
||||||
afterthought.analyze(settings, definition, variables);
|
afterthought.analyze(settings, variables);
|
||||||
|
|
||||||
if (!afterthought.statement) {
|
if (!afterthought.statement) {
|
||||||
throw new IllegalArgumentException(afterthought.error("Not a statement."));
|
throw new IllegalArgumentException(afterthought.error("Not a statement."));
|
||||||
|
@ -104,7 +104,7 @@ public final class SFor extends AStatement {
|
||||||
block.beginLoop = true;
|
block.beginLoop = true;
|
||||||
block.inLoop = true;
|
block.inLoop = true;
|
||||||
|
|
||||||
block.analyze(settings, definition, variables);
|
block.analyze(settings, variables);
|
||||||
|
|
||||||
if (block.loopEscape && !block.anyContinue) {
|
if (block.loopEscape && !block.anyContinue) {
|
||||||
throw new IllegalArgumentException(error("Extraneous for loop."));
|
throw new IllegalArgumentException(error("Extraneous for loop."));
|
||||||
|
@ -128,18 +128,18 @@ public final class SFor extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
final Label start = new Label();
|
final Label start = new Label();
|
||||||
final Label begin = afterthought == null ? start : new Label();
|
final Label begin = afterthought == null ? start : new Label();
|
||||||
final Label end = new Label();
|
final Label end = new Label();
|
||||||
|
|
||||||
if (initializer instanceof SDeclBlock) {
|
if (initializer instanceof SDeclBlock) {
|
||||||
((SDeclBlock)initializer).write(settings, definition, adapter);
|
((SDeclBlock)initializer).write(settings, adapter);
|
||||||
} else if (initializer instanceof AExpression) {
|
} else if (initializer instanceof AExpression) {
|
||||||
AExpression initializer = (AExpression)this.initializer;
|
AExpression initializer = (AExpression)this.initializer;
|
||||||
|
|
||||||
initializer.write(settings, definition, adapter);
|
initializer.write(settings, adapter);
|
||||||
adapter.writePop(initializer.expected.sort.size);
|
adapter.writePop(initializer.expected.sort.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ public final class SFor extends AStatement {
|
||||||
|
|
||||||
if (condition != null) {
|
if (condition != null) {
|
||||||
condition.fals = end;
|
condition.fals = end;
|
||||||
condition.write(settings, definition, adapter);
|
condition.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean allEscape = false;
|
boolean allEscape = false;
|
||||||
|
@ -162,14 +162,14 @@ public final class SFor extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.writeLoopCounter(loopCounterSlot, statementCount);
|
adapter.writeLoopCounter(loopCounterSlot, statementCount);
|
||||||
block.write(settings, definition, adapter);
|
block.write(settings, adapter);
|
||||||
} else {
|
} else {
|
||||||
adapter.writeLoopCounter(loopCounterSlot, 1);
|
adapter.writeLoopCounter(loopCounterSlot, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afterthought != null) {
|
if (afterthought != null) {
|
||||||
adapter.mark(begin);
|
adapter.mark(begin);
|
||||||
afterthought.write(settings, definition, adapter);
|
afterthought.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afterthought != null || !allEscape) {
|
if (afterthought != null || !allEscape) {
|
||||||
|
|
|
@ -44,10 +44,10 @@ public final class SIfElse extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
condition.expected = Definition.booleanType;
|
condition.expected = Definition.booleanType;
|
||||||
condition.analyze(settings, definition, variables);
|
condition.analyze(settings, variables);
|
||||||
condition = condition.cast(settings, definition, variables);
|
condition = condition.cast(settings, variables);
|
||||||
|
|
||||||
if (condition.constant != null) {
|
if (condition.constant != null) {
|
||||||
throw new IllegalArgumentException(error("Extraneous if statement."));
|
throw new IllegalArgumentException(error("Extraneous if statement."));
|
||||||
|
@ -58,7 +58,7 @@ public final class SIfElse extends AStatement {
|
||||||
ifblock.lastLoop = lastLoop;
|
ifblock.lastLoop = lastLoop;
|
||||||
|
|
||||||
variables.incrementScope();
|
variables.incrementScope();
|
||||||
ifblock.analyze(settings, definition, variables);
|
ifblock.analyze(settings, variables);
|
||||||
variables.decrementScope();
|
variables.decrementScope();
|
||||||
|
|
||||||
anyContinue = ifblock.anyContinue;
|
anyContinue = ifblock.anyContinue;
|
||||||
|
@ -71,7 +71,7 @@ public final class SIfElse extends AStatement {
|
||||||
elseblock.lastLoop = lastLoop;
|
elseblock.lastLoop = lastLoop;
|
||||||
|
|
||||||
variables.incrementScope();
|
variables.incrementScope();
|
||||||
elseblock.analyze(settings, definition, variables);
|
elseblock.analyze(settings, variables);
|
||||||
variables.decrementScope();
|
variables.decrementScope();
|
||||||
|
|
||||||
methodEscape = ifblock.methodEscape && elseblock.methodEscape;
|
methodEscape = ifblock.methodEscape && elseblock.methodEscape;
|
||||||
|
@ -84,17 +84,17 @@ public final class SIfElse extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
final Label end = new Label();
|
final Label end = new Label();
|
||||||
final Label fals = elseblock != null ? new Label() : end;
|
final Label fals = elseblock != null ? new Label() : end;
|
||||||
|
|
||||||
condition.fals = fals;
|
condition.fals = fals;
|
||||||
condition.write(settings, definition, adapter);
|
condition.write(settings, adapter);
|
||||||
|
|
||||||
ifblock.continu = continu;
|
ifblock.continu = continu;
|
||||||
ifblock.brake = brake;
|
ifblock.brake = brake;
|
||||||
ifblock.write(settings, definition, adapter);
|
ifblock.write(settings, adapter);
|
||||||
|
|
||||||
if (elseblock != null) {
|
if (elseblock != null) {
|
||||||
if (!ifblock.allEscape) {
|
if (!ifblock.allEscape) {
|
||||||
|
@ -105,7 +105,7 @@ public final class SIfElse extends AStatement {
|
||||||
|
|
||||||
elseblock.continu = continu;
|
elseblock.continu = continu;
|
||||||
elseblock.brake = brake;
|
elseblock.brake = brake;
|
||||||
elseblock.write(settings, definition, adapter);
|
elseblock.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.mark(end);
|
adapter.mark(end);
|
||||||
|
|
|
@ -38,10 +38,10 @@ public final class SReturn extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
expression.expected = Definition.objectType;
|
expression.expected = Definition.objectType;
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
expression = expression.cast(settings, definition, variables);
|
expression = expression.cast(settings, variables);
|
||||||
|
|
||||||
methodEscape = true;
|
methodEscape = true;
|
||||||
loopEscape = true;
|
loopEscape = true;
|
||||||
|
@ -51,9 +51,9 @@ public final class SReturn extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
expression.write(settings, definition, adapter);
|
expression.write(settings, adapter);
|
||||||
adapter.returnValue();
|
adapter.returnValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
@ -42,7 +41,7 @@ public final class SSource extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
public void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
variables.incrementScope();
|
variables.incrementScope();
|
||||||
|
|
||||||
final AStatement last = statements.get(statements.size() - 1);
|
final AStatement last = statements.get(statements.size() - 1);
|
||||||
|
@ -53,7 +52,7 @@ public final class SSource extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
statement.lastSource = statement == last;
|
statement.lastSource = statement == last;
|
||||||
statement.analyze(settings, definition, variables);
|
statement.analyze(settings, variables);
|
||||||
|
|
||||||
methodEscape = statement.methodEscape;
|
methodEscape = statement.methodEscape;
|
||||||
allEscape = statement.allEscape;
|
allEscape = statement.allEscape;
|
||||||
|
@ -63,9 +62,9 @@ public final class SSource extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
public void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
for (final AStatement statement : statements) {
|
for (final AStatement statement : statements) {
|
||||||
statement.write(settings, definition, adapter);
|
statement.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!methodEscape) {
|
if (!methodEscape) {
|
||||||
|
|
|
@ -38,10 +38,10 @@ public final class SThrow extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
expression.expected = Definition.exceptionType;
|
expression.expected = Definition.exceptionType;
|
||||||
expression.analyze(settings, definition, variables);
|
expression.analyze(settings, variables);
|
||||||
expression = expression.cast(settings, definition, variables);
|
expression = expression.cast(settings, variables);
|
||||||
|
|
||||||
methodEscape = true;
|
methodEscape = true;
|
||||||
loopEscape = true;
|
loopEscape = true;
|
||||||
|
@ -50,9 +50,9 @@ public final class SThrow extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
expression.write(settings, definition, adapter);
|
expression.write(settings, adapter);
|
||||||
adapter.throwException();
|
adapter.throwException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.elasticsearch.painless.Variables.Variable;
|
import org.elasticsearch.painless.Variables.Variable;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
|
@ -51,7 +50,7 @@ public final class STrap extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
variable = variables.addVariable(location, type, name, true, false);
|
variable = variables.addVariable(location, type, name, true, false);
|
||||||
|
|
||||||
if (!Exception.class.isAssignableFrom(variable.type.clazz)) {
|
if (!Exception.class.isAssignableFrom(variable.type.clazz)) {
|
||||||
|
@ -63,7 +62,7 @@ public final class STrap extends AStatement {
|
||||||
block.inLoop = inLoop;
|
block.inLoop = inLoop;
|
||||||
block.lastLoop = lastLoop;
|
block.lastLoop = lastLoop;
|
||||||
|
|
||||||
block.analyze(settings, definition, variables);
|
block.analyze(settings, variables);
|
||||||
|
|
||||||
methodEscape = block.methodEscape;
|
methodEscape = block.methodEscape;
|
||||||
loopEscape = block.loopEscape;
|
loopEscape = block.loopEscape;
|
||||||
|
@ -75,7 +74,7 @@ public final class STrap extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
final Label jump = new Label();
|
final Label jump = new Label();
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ public final class STrap extends AStatement {
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
block.continu = continu;
|
block.continu = continu;
|
||||||
block.brake = brake;
|
block.brake = brake;
|
||||||
block.write(settings, definition, adapter);
|
block.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.visitTryCatchBlock(begin, end, jump, variable.type.type.getInternalName());
|
adapter.visitTryCatchBlock(begin, end, jump, variable.type.type.getInternalName());
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Definition;
|
|
||||||
import org.elasticsearch.painless.Variables;
|
import org.elasticsearch.painless.Variables;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
@ -44,13 +43,13 @@ public final class STry extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
block.lastSource = lastSource;
|
block.lastSource = lastSource;
|
||||||
block.inLoop = inLoop;
|
block.inLoop = inLoop;
|
||||||
block.lastLoop = lastLoop;
|
block.lastLoop = lastLoop;
|
||||||
|
|
||||||
variables.incrementScope();
|
variables.incrementScope();
|
||||||
block.analyze(settings, definition, variables);
|
block.analyze(settings, variables);
|
||||||
variables.decrementScope();
|
variables.decrementScope();
|
||||||
|
|
||||||
methodEscape = block.methodEscape;
|
methodEscape = block.methodEscape;
|
||||||
|
@ -67,7 +66,7 @@ public final class STry extends AStatement {
|
||||||
trap.lastLoop = lastLoop;
|
trap.lastLoop = lastLoop;
|
||||||
|
|
||||||
variables.incrementScope();
|
variables.incrementScope();
|
||||||
trap.analyze(settings, definition, variables);
|
trap.analyze(settings, variables);
|
||||||
variables.decrementScope();
|
variables.decrementScope();
|
||||||
|
|
||||||
methodEscape &= trap.methodEscape;
|
methodEscape &= trap.methodEscape;
|
||||||
|
@ -83,7 +82,7 @@ public final class STry extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
final Label begin = new Label();
|
final Label begin = new Label();
|
||||||
final Label end = new Label();
|
final Label end = new Label();
|
||||||
|
@ -93,7 +92,7 @@ public final class STry extends AStatement {
|
||||||
|
|
||||||
block.continu = continu;
|
block.continu = continu;
|
||||||
block.brake = brake;
|
block.brake = brake;
|
||||||
block.write(settings, definition, adapter);
|
block.write(settings, adapter);
|
||||||
|
|
||||||
if (!block.allEscape) {
|
if (!block.allEscape) {
|
||||||
adapter.goTo(exception);
|
adapter.goTo(exception);
|
||||||
|
@ -105,7 +104,7 @@ public final class STry extends AStatement {
|
||||||
trap.begin = begin;
|
trap.begin = begin;
|
||||||
trap.end = end;
|
trap.end = end;
|
||||||
trap.exception = traps.size() > 1 ? exception : null;
|
trap.exception = traps.size() > 1 ? exception : null;
|
||||||
trap.write(settings, definition, adapter);
|
trap.write(settings, adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!block.allEscape || traps.size() > 1) {
|
if (!block.allEscape || traps.size() > 1) {
|
||||||
|
|
|
@ -41,12 +41,12 @@ public final class SWhile extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
void analyze(final CompilerSettings settings, final Variables variables) {
|
||||||
variables.incrementScope();
|
variables.incrementScope();
|
||||||
|
|
||||||
condition.expected = Definition.booleanType;
|
condition.expected = Definition.booleanType;
|
||||||
condition.analyze(settings, definition, variables);
|
condition.analyze(settings, variables);
|
||||||
condition = condition.cast(settings, definition, variables);
|
condition = condition.cast(settings, variables);
|
||||||
|
|
||||||
boolean continuous = false;
|
boolean continuous = false;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public final class SWhile extends AStatement {
|
||||||
block.beginLoop = true;
|
block.beginLoop = true;
|
||||||
block.inLoop = true;
|
block.inLoop = true;
|
||||||
|
|
||||||
block.analyze(settings, definition, variables);
|
block.analyze(settings, variables);
|
||||||
|
|
||||||
if (block.loopEscape && !block.anyContinue) {
|
if (block.loopEscape && !block.anyContinue) {
|
||||||
throw new IllegalArgumentException(error("Extranous while loop."));
|
throw new IllegalArgumentException(error("Extranous while loop."));
|
||||||
|
@ -92,7 +92,7 @@ public final class SWhile extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) {
|
void write(final CompilerSettings settings, final MethodWriter adapter) {
|
||||||
writeDebugInfo(adapter);
|
writeDebugInfo(adapter);
|
||||||
final Label begin = new Label();
|
final Label begin = new Label();
|
||||||
final Label end = new Label();
|
final Label end = new Label();
|
||||||
|
@ -100,14 +100,14 @@ public final class SWhile extends AStatement {
|
||||||
adapter.mark(begin);
|
adapter.mark(begin);
|
||||||
|
|
||||||
condition.fals = end;
|
condition.fals = end;
|
||||||
condition.write(settings, definition, adapter);
|
condition.write(settings, adapter);
|
||||||
|
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
adapter.writeLoopCounter(loopCounterSlot, Math.max(1, block.statementCount));
|
adapter.writeLoopCounter(loopCounterSlot, Math.max(1, block.statementCount));
|
||||||
|
|
||||||
block.continu = begin;
|
block.continu = begin;
|
||||||
block.brake = end;
|
block.brake = end;
|
||||||
block.write(settings, definition, adapter);
|
block.write(settings, adapter);
|
||||||
} else {
|
} else {
|
||||||
adapter.writeLoopCounter(loopCounterSlot, 1);
|
adapter.writeLoopCounter(loopCounterSlot, 1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue