Search in sources :

Example 1 with Type

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);
}
Also used : Type(org.elasticsearch.painless.Definition.Type) Label(org.objectweb.asm.Label)

Example 2 with Type

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."));
        }
    }
}
Also used : Type(org.elasticsearch.painless.Definition.Type) Sort(org.elasticsearch.painless.Definition.Sort)

Example 3 with Type

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."));
        }
    }
}
Also used : Type(org.elasticsearch.painless.Definition.Type) Sort(org.elasticsearch.painless.Definition.Sort)

Example 4 with Type

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;
    }
}
Also used : Variable(org.elasticsearch.painless.Locals.Variable) ArrayList(java.util.ArrayList) Method(org.elasticsearch.painless.Definition.Method) Type(org.elasticsearch.painless.Definition.Type) HashSet(java.util.HashSet) FunctionRef(org.elasticsearch.painless.FunctionRef)

Example 5 with Type

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());
}
Also used : Type(org.elasticsearch.painless.Definition.Type)

Aggregations

Type (org.elasticsearch.painless.Definition.Type)18 Method (org.elasticsearch.painless.Definition.Method)3 Sort (org.elasticsearch.painless.Definition.Sort)3 ArrayList (java.util.ArrayList)2 Struct (org.elasticsearch.painless.Definition.Struct)2 Variable (org.elasticsearch.painless.Locals.Variable)2 IOException (java.io.IOException)1 PrintStream (java.io.PrintStream)1 MethodType (java.lang.invoke.MethodType)1 Modifier (java.lang.reflect.Modifier)1 StandardCharsets (java.nio.charset.StandardCharsets)1 Files (java.nio.file.Files)1 Path (java.nio.file.Path)1 StandardOpenOption (java.nio.file.StandardOpenOption)1 Comparator (java.util.Comparator)1 Comparator.comparing (java.util.Comparator.comparing)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1