use of org.elasticsearch.painless.Definition.Type in project elasticsearch by elastic.
the class SSubEachIterable method write.
@Override
void write(MethodWriter writer, Globals globals) {
writer.writeStatementOffset(location);
expression.write(writer, globals);
if (method == null) {
Type itr = Definition.getType("Iterator");
org.objectweb.asm.Type methodType = org.objectweb.asm.Type.getMethodType(itr.type, Definition.DEF_TYPE.type);
writer.invokeDefCall("iterator", methodType, DefBootstrap.ITERATOR);
} else {
method.write(writer);
}
writer.visitVarInsn(iterator.type.type.getOpcode(Opcodes.ISTORE), iterator.getSlot());
Label begin = new Label();
Label end = new Label();
writer.mark(begin);
writer.visitVarInsn(iterator.type.type.getOpcode(Opcodes.ILOAD), iterator.getSlot());
writer.invokeInterface(ITERATOR_TYPE, ITERATOR_HASNEXT);
writer.ifZCmp(MethodWriter.EQ, end);
writer.visitVarInsn(iterator.type.type.getOpcode(Opcodes.ILOAD), iterator.getSlot());
writer.invokeInterface(ITERATOR_TYPE, ITERATOR_NEXT);
writer.writeCast(cast);
writer.visitVarInsn(variable.type.type.getOpcode(Opcodes.ISTORE), variable.getSlot());
if (loopCounter != null) {
writer.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
}
block.continu = begin;
block.brake = end;
block.write(writer, globals);
writer.goTo(begin);
writer.mark(end);
}
use of org.elasticsearch.painless.Definition.Type in project elasticsearch by elastic.
the class EBinary method analyzeLSH.
private void analyzeLSH(Locals variables) {
left.analyze(variables);
right.analyze(variables);
Type lhspromote = AnalyzerCaster.promoteNumeric(left.actual, false);
Type rhspromote = AnalyzerCaster.promoteNumeric(right.actual, false);
if (lhspromote == null || rhspromote == null) {
throw createError(new ClassCastException("Cannot apply left shift [<<] to types " + "[" + left.actual.name + "] and [" + right.actual.name + "]."));
}
actual = promote = lhspromote;
shiftDistance = rhspromote;
if (lhspromote.sort == Sort.DEF || rhspromote.sort == Sort.DEF) {
left.expected = left.actual;
right.expected = right.actual;
if (expected != null) {
actual = expected;
}
} else {
left.expected = lhspromote;
if (rhspromote.sort == Sort.LONG) {
right.expected = Definition.INT_TYPE;
right.explicit = true;
} else {
right.expected = rhspromote;
}
}
left = left.cast(variables);
right = right.cast(variables);
if (left.constant != null && right.constant != null) {
Sort sort = lhspromote.sort;
if (sort == Sort.INT) {
constant = (int) left.constant << (int) right.constant;
} else if (sort == Sort.LONG) {
constant = (long) left.constant << (int) right.constant;
} else {
throw createError(new IllegalStateException("Illegal tree structure."));
}
}
}
use of org.elasticsearch.painless.Definition.Type in project elasticsearch by elastic.
the class EBinary method analyzeRSH.
private void analyzeRSH(Locals variables) {
left.analyze(variables);
right.analyze(variables);
Type lhspromote = AnalyzerCaster.promoteNumeric(left.actual, false);
Type rhspromote = AnalyzerCaster.promoteNumeric(right.actual, false);
if (lhspromote == null || rhspromote == null) {
throw createError(new ClassCastException("Cannot apply right shift [>>] to types " + "[" + left.actual.name + "] and [" + right.actual.name + "]."));
}
actual = promote = lhspromote;
shiftDistance = rhspromote;
if (lhspromote.sort == Sort.DEF || rhspromote.sort == Sort.DEF) {
left.expected = left.actual;
right.expected = right.actual;
if (expected != null) {
actual = expected;
}
} else {
left.expected = lhspromote;
if (rhspromote.sort == Sort.LONG) {
right.expected = Definition.INT_TYPE;
right.explicit = true;
} else {
right.expected = rhspromote;
}
}
left = left.cast(variables);
right = right.cast(variables);
if (left.constant != null && right.constant != null) {
Sort sort = lhspromote.sort;
if (sort == Sort.INT) {
constant = (int) left.constant >> (int) right.constant;
} else if (sort == Sort.LONG) {
constant = (long) left.constant >> (int) right.constant;
} else {
throw createError(new IllegalStateException("Illegal tree structure."));
}
}
}
use of org.elasticsearch.painless.Definition.Type in project elasticsearch by elastic.
the class ELambda method analyze.
@Override
void analyze(Locals locals) {
final Type returnType;
final List<String> actualParamTypeStrs;
Method interfaceMethod;
// inspect the target first, set interface method if we know it.
if (expected == null) {
interfaceMethod = null;
// we don't know anything: treat as def
returnType = Definition.DEF_TYPE;
// don't infer any types
actualParamTypeStrs = paramTypeStrs;
} else {
// we know the method statically, infer return type and any unknown/def types
interfaceMethod = expected.struct.getFunctionalMethod();
if (interfaceMethod == null) {
throw createError(new IllegalArgumentException("Cannot pass lambda to [" + expected.name + "], not a functional interface"));
}
// check arity before we manipulate parameters
if (interfaceMethod.arguments.size() != paramTypeStrs.size())
throw new IllegalArgumentException("Incorrect number of parameters for [" + interfaceMethod.name + "] in [" + expected.clazz + "]");
// for method invocation, its allowed to ignore the return value
if (interfaceMethod.rtn == Definition.VOID_TYPE) {
returnType = Definition.DEF_TYPE;
} else {
returnType = interfaceMethod.rtn;
}
// replace any def types with the actual type (which could still be def)
actualParamTypeStrs = new ArrayList<String>();
for (int i = 0; i < paramTypeStrs.size(); i++) {
String paramType = paramTypeStrs.get(i);
if (paramType.equals(Definition.DEF_TYPE.name)) {
actualParamTypeStrs.add(interfaceMethod.arguments.get(i).name);
} else {
actualParamTypeStrs.add(paramType);
}
}
}
// gather any variables used by the lambda body first.
Set<String> variables = new HashSet<>();
for (AStatement statement : statements) {
statement.extractVariables(variables);
}
// any of those variables defined in our scope need to be captured
captures = new ArrayList<>();
for (String variable : variables) {
if (locals.hasVariable(variable)) {
captures.add(locals.getVariable(location, variable));
}
}
// prepend capture list to lambda's arguments
List<String> paramTypes = new ArrayList<>();
List<String> paramNames = new ArrayList<>();
for (Variable var : captures) {
paramTypes.add(var.type.name);
paramNames.add(var.name);
}
paramTypes.addAll(actualParamTypeStrs);
paramNames.addAll(paramNameStrs);
// desugar lambda body into a synthetic method
desugared = new SFunction(reserved, location, returnType.name, name, paramTypes, paramNames, statements, true);
desugared.generateSignature();
desugared.analyze(Locals.newLambdaScope(locals.getProgramScope(), returnType, desugared.parameters, captures.size(), reserved.getMaxLoopCounter()));
// setup method reference to synthetic method
if (expected == null) {
ref = null;
actual = Definition.getType("String");
defPointer = "Sthis." + name + "," + captures.size();
} else {
defPointer = null;
try {
ref = new FunctionRef(expected, interfaceMethod, desugared.method, captures.size());
} catch (IllegalArgumentException e) {
throw createError(e);
}
actual = expected;
}
}
use of org.elasticsearch.painless.Definition.Type in project elasticsearch by elastic.
the class ENewArray method analyze.
@Override
void analyze(Locals locals) {
if (!read) {
throw createError(new IllegalArgumentException("A newly created array must be read from."));
}
final Type type;
try {
type = Definition.getType(this.type);
} catch (IllegalArgumentException exception) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
for (int argument = 0; argument < arguments.size(); ++argument) {
AExpression expression = arguments.get(argument);
expression.expected = initialize ? Definition.getType(type.struct, 0) : Definition.INT_TYPE;
expression.internal = true;
expression.analyze(locals);
arguments.set(argument, expression.cast(locals));
}
actual = Definition.getType(type.struct, initialize ? 1 : arguments.size());
}
Aggregations