Skip to content

Commit 0c918a6

Browse files
committed
Allow for the Painless Definition to have multiple instances (#27096)
1 parent 6a9528e commit 0c918a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+611
-607
lines changed

modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java

+249-266
Large diffs are not rendered by default.

modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java

+84-57
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,19 @@
1919

2020
package org.elasticsearch.painless;
2121

22-
import org.apache.lucene.util.Constants;
2322
import org.apache.lucene.util.SetOnce;
2423

2524
import java.lang.invoke.MethodHandle;
2625
import java.lang.invoke.MethodHandles;
2726
import java.lang.invoke.MethodType;
2827
import java.lang.reflect.Modifier;
29-
import java.time.LocalDate;
3028
import java.util.ArrayList;
31-
import java.util.Arrays;
3229
import java.util.Collection;
3330
import java.util.Collections;
3431
import java.util.HashMap;
3532
import java.util.List;
3633
import java.util.Map;
3734
import java.util.Objects;
38-
import java.util.PrimitiveIterator;
39-
import java.util.Spliterator;
4035
import java.util.Stack;
4136

4237
/**
@@ -65,37 +60,37 @@ public final class Definition {
6560
/**
6661
* Whitelist that is "built in" to Painless and required by all scripts.
6762
*/
68-
public static final Definition BUILTINS = new Definition(
63+
public static final Definition DEFINITION = new Definition(
6964
Collections.singletonList(WhitelistLoader.loadFromResourceFiles(Definition.class, DEFINITION_FILES)));
7065

7166
/** Some native types as constants: */
72-
public static final Type VOID_TYPE = BUILTINS.getType("void");
73-
public static final Type BOOLEAN_TYPE = BUILTINS.getType("boolean");
74-
public static final Type BOOLEAN_OBJ_TYPE = BUILTINS.getType("Boolean");
75-
public static final Type BYTE_TYPE = BUILTINS.getType("byte");
76-
public static final Type BYTE_OBJ_TYPE = BUILTINS.getType("Byte");
77-
public static final Type SHORT_TYPE = BUILTINS.getType("short");
78-
public static final Type SHORT_OBJ_TYPE = BUILTINS.getType("Short");
79-
public static final Type INT_TYPE = BUILTINS.getType("int");
80-
public static final Type INT_OBJ_TYPE = BUILTINS.getType("Integer");
81-
public static final Type LONG_TYPE = BUILTINS.getType("long");
82-
public static final Type LONG_OBJ_TYPE = BUILTINS.getType("Long");
83-
public static final Type FLOAT_TYPE = BUILTINS.getType("float");
84-
public static final Type FLOAT_OBJ_TYPE = BUILTINS.getType("Float");
85-
public static final Type DOUBLE_TYPE = BUILTINS.getType("double");
86-
public static final Type DOUBLE_OBJ_TYPE = BUILTINS.getType("Double");
87-
public static final Type CHAR_TYPE = BUILTINS.getType("char");
88-
public static final Type CHAR_OBJ_TYPE = BUILTINS.getType("Character");
89-
public static final Type OBJECT_TYPE = BUILTINS.getType("Object");
90-
public static final Type DEF_TYPE = BUILTINS.getType("def");
91-
public static final Type NUMBER_TYPE = BUILTINS.getType("Number");
92-
public static final Type STRING_TYPE = BUILTINS.getType("String");
93-
public static final Type EXCEPTION_TYPE = BUILTINS.getType("Exception");
94-
public static final Type PATTERN_TYPE = BUILTINS.getType("Pattern");
95-
public static final Type MATCHER_TYPE = BUILTINS.getType("Matcher");
96-
public static final Type ITERATOR_TYPE = BUILTINS.getType("Iterator");
97-
public static final Type ARRAY_LIST_TYPE = BUILTINS.getType("ArrayList");
98-
public static final Type HASH_MAP_TYPE = BUILTINS.getType("HashMap");
67+
public final Type voidType;
68+
public final Type booleanType;
69+
public final Type BooleanType;
70+
public final Type byteType;
71+
public final Type ByteType;
72+
public final Type shortType;
73+
public final Type ShortType;
74+
public final Type intType;
75+
public final Type IntegerType;
76+
public final Type longType;
77+
public final Type LongType;
78+
public final Type floatType;
79+
public final Type FloatType;
80+
public final Type doubleType;
81+
public final Type DoubleType;
82+
public final Type charType;
83+
public final Type CharacterType;
84+
public final Type ObjectType;
85+
public final Type DefType;
86+
public final Type NumberType;
87+
public final Type StringType;
88+
public final Type ExceptionType;
89+
public final Type PatternType;
90+
public final Type MatcherType;
91+
public final Type IteratorType;
92+
public final Type ArrayListType;
93+
public final Type HashMapType;
9994

10095
public static final class Type {
10196
public final String name;
@@ -438,58 +433,58 @@ public Struct getStruct() {
438433

439434
/** Returns whether or not a non-array type exists. */
440435
public boolean isSimpleType(final String name) {
441-
return BUILTINS.structsMap.containsKey(name);
436+
return structsMap.containsKey(name);
442437
}
443438

444439
/** Gets the type given by its name */
445440
public Type getType(final String name) {
446-
return BUILTINS.getTypeInternal(name);
441+
return getTypeInternal(name);
447442
}
448443

449444
/** Creates an array type from the given Struct. */
450445
public Type getType(final Struct struct, final int dimensions) {
451-
return BUILTINS.getTypeInternal(struct, dimensions);
446+
return getTypeInternal(struct, dimensions);
452447
}
453448

454-
public static Type getBoxedType(Type unboxed) {
449+
public Type getBoxedType(Type unboxed) {
455450
if (unboxed.clazz == boolean.class) {
456-
return BOOLEAN_OBJ_TYPE;
451+
return BooleanType;
457452
} else if (unboxed.clazz == byte.class) {
458-
return BYTE_OBJ_TYPE;
453+
return ByteType;
459454
} else if (unboxed.clazz == short.class) {
460-
return SHORT_OBJ_TYPE;
455+
return ShortType;
461456
} else if (unboxed.clazz == char.class) {
462-
return CHAR_OBJ_TYPE;
457+
return CharacterType;
463458
} else if (unboxed.clazz == int.class) {
464-
return INT_OBJ_TYPE;
459+
return IntegerType;
465460
} else if (unboxed.clazz == long.class) {
466-
return LONG_OBJ_TYPE;
461+
return LongType;
467462
} else if (unboxed.clazz == float.class) {
468-
return FLOAT_OBJ_TYPE;
463+
return FloatType;
469464
} else if (unboxed.clazz == double.class) {
470-
return DOUBLE_OBJ_TYPE;
465+
return DoubleType;
471466
}
472467

473468
return unboxed;
474469
}
475470

476-
public static Type getUnboxedType(Type boxed) {
471+
public Type getUnboxedType(Type boxed) {
477472
if (boxed.clazz == Boolean.class) {
478-
return BOOLEAN_TYPE;
473+
return booleanType;
479474
} else if (boxed.clazz == Byte.class) {
480-
return BYTE_TYPE;
475+
return byteType;
481476
} else if (boxed.clazz == Short.class) {
482-
return SHORT_TYPE;
477+
return shortType;
483478
} else if (boxed.clazz == Character.class) {
484-
return CHAR_TYPE;
479+
return charType;
485480
} else if (boxed.clazz == Integer.class) {
486-
return INT_TYPE;
481+
return intType;
487482
} else if (boxed.clazz == Long.class) {
488-
return LONG_TYPE;
483+
return longType;
489484
} else if (boxed.clazz == Float.class) {
490-
return FLOAT_TYPE;
485+
return floatType;
491486
} else if (boxed.clazz == Double.class) {
492-
return DOUBLE_TYPE;
487+
return doubleType;
493488
}
494489

495490
return boxed;
@@ -508,12 +503,12 @@ public static boolean isConstantType(Type constant) {
508503
}
509504

510505
public RuntimeClass getRuntimeClass(Class<?> clazz) {
511-
return BUILTINS.runtimeMap.get(clazz);
506+
return runtimeMap.get(clazz);
512507
}
513508

514509
/** Collection of all simple types. Used by {@code PainlessDocGenerator} to generate an API reference. */
515-
static Collection<Type> allSimpleTypes() {
516-
return BUILTINS.simpleTypesMap.values();
510+
Collection<Type> allSimpleTypes() {
511+
return simpleTypesMap.values();
517512
}
518513

519514
// INTERNAL IMPLEMENTATION:
@@ -522,6 +517,8 @@ static Collection<Type> allSimpleTypes() {
522517
private final Map<String, Struct> structsMap;
523518
private final Map<String, Type> simpleTypesMap;
524519

520+
public AnalyzerCaster caster;
521+
525522
private Definition(List<Whitelist> whitelists) {
526523
structsMap = new HashMap<>();
527524
simpleTypesMap = new HashMap<>();
@@ -648,6 +645,36 @@ private Definition(List<Whitelist> whitelists) {
648645
for (final Map.Entry<String,Struct> entry : structsMap.entrySet()) {
649646
entry.setValue(entry.getValue().freeze());
650647
}
648+
649+
voidType = getType("void");
650+
booleanType = getType("boolean");
651+
BooleanType = getType("Boolean");
652+
byteType = getType("byte");
653+
ByteType = getType("Byte");
654+
shortType = getType("short");
655+
ShortType = getType("Short");
656+
intType = getType("int");
657+
IntegerType = getType("Integer");
658+
longType = getType("long");
659+
LongType = getType("Long");
660+
floatType = getType("float");
661+
FloatType = getType("Float");
662+
doubleType = getType("double");
663+
DoubleType = getType("Double");
664+
charType = getType("char");
665+
CharacterType = getType("Character");
666+
ObjectType = getType("Object");
667+
DefType = getType("def");
668+
NumberType = getType("Number");
669+
StringType = getType("String");
670+
ExceptionType = getType("Exception");
671+
PatternType = getType("Pattern");
672+
MatcherType = getType("Matcher");
673+
IteratorType = getType("Iterator");
674+
ArrayListType = getType("ArrayList");
675+
HashMapType = getType("HashMap");
676+
677+
caster = new AnalyzerCaster(this);
651678
}
652679

653680
private void addStruct(ClassLoader whitelistClassLoader, Whitelist.Struct whitelistStruct) {

modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public static Locals newLambdaScope(Locals programScope, Type returnType, List<P
7272
}
7373
// Loop counter to catch infinite loops. Internal use only.
7474
if (maxLoopCounter > 0) {
75-
locals.defineVariable(null, Definition.INT_TYPE, LOOP, true);
75+
locals.defineVariable(null, locals.getDefinition().intType, LOOP, true);
7676
}
7777
return locals;
7878
}
@@ -85,7 +85,7 @@ public static Locals newFunctionScope(Locals programScope, Type returnType, List
8585
}
8686
// Loop counter to catch infinite loops. Internal use only.
8787
if (maxLoopCounter > 0) {
88-
locals.defineVariable(null, Definition.INT_TYPE, LOOP, true);
88+
locals.defineVariable(null, locals.getDefinition().intType, LOOP, true);
8989
}
9090
return locals;
9191
}
@@ -104,7 +104,7 @@ public static Locals newMainMethodScope(ScriptClassInfo scriptClassInfo, Locals
104104

105105
// Loop counter to catch infinite loops. Internal use only.
106106
if (maxLoopCounter > 0) {
107-
locals.defineVariable(null, Definition.INT_TYPE, LOOP, true);
107+
locals.defineVariable(null, locals.getDefinition().intType, LOOP, true);
108108
}
109109
return locals;
110110
}

modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public final class PainlessPlugin extends Plugin implements ScriptPlugin {
3838

3939
// force to parse our definition at startup (not on the user's first script)
4040
static {
41-
Definition.VOID_TYPE.hashCode();
41+
Definition.DEFINITION.hashCode();
4242
}
4343

4444
@Override

modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngine.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ public PainlessScriptEngine(Settings settings, Collection<ScriptContext<?>> cont
101101

102102
for (ScriptContext<?> context : contexts) {
103103
if (context.instanceClazz.equals(SearchScript.class) || context.instanceClazz.equals(ExecutableScript.class)) {
104-
contextsToCompilers.put(context, new Compiler(GenericElasticsearchScript.class, Definition.BUILTINS));
104+
contextsToCompilers.put(context, new Compiler(GenericElasticsearchScript.class, Definition.DEFINITION));
105105
} else {
106-
contextsToCompilers.put(context, new Compiler(context.instanceClazz, Definition.BUILTINS));
106+
contextsToCompilers.put(context, new Compiler(context.instanceClazz, Definition.DEFINITION));
107107
}
108108
}
109109

modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ private static Definition.Type definitionTypeForClass(Definition definition, Cla
191191
}
192192
Definition.Struct struct;
193193
if (componentType.equals(Object.class)) {
194-
struct = Definition.DEF_TYPE.struct;
194+
struct = definition.DefType.struct;
195195
} else {
196196
Definition.RuntimeClass runtimeClass = definition.getRuntimeClass(componentType);
197197
if (runtimeClass == null) {

modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public final class WriterConstants {
137137
public static final Method DEF_TO_LONG_EXPLICIT = getAsmMethod(long.class , "DefTolongExplicit" , Object.class);
138138
public static final Method DEF_TO_FLOAT_EXPLICIT = getAsmMethod(float.class , "DefTofloatExplicit" , Object.class);
139139
public static final Method DEF_TO_DOUBLE_EXPLICIT = getAsmMethod(double.class , "DefTodoubleExplicit", Object.class);
140-
public static final Type DEF_ARRAY_LENGTH_METHOD_TYPE = Type.getMethodType(Type.INT_TYPE, Definition.DEF_TYPE.type);
140+
public static final Type DEF_ARRAY_LENGTH_METHOD_TYPE = Type.getMethodType(Type.INT_TYPE, Type.getType(Object.class));
141141

142142
/** invokedynamic bootstrap for lambda expression/method references */
143143
public static final MethodType LAMBDA_BOOTSTRAP_TYPE =

modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public abstract class AExpression extends ANode {
119119
* @return The new child node for the parent node calling this method.
120120
*/
121121
AExpression cast(Locals locals) {
122-
Cast cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit, internal);
122+
Cast cast = locals.getDefinition().caster.getLegalCast(location, actual, expected, explicit, internal);
123123

124124
if (cast == null) {
125125
if (constant == null || this instanceof EConstant) {
@@ -167,7 +167,7 @@ AExpression cast(Locals locals) {
167167
// from this node because the output data for the EConstant
168168
// will already be the same.
169169

170-
constant = AnalyzerCaster.constCast(location, constant, cast);
170+
constant = locals.getDefinition().caster.constCast(location, constant, cast);
171171

172172
EConstant econstant = new EConstant(location, constant);
173173
econstant.analyze(locals);

0 commit comments

Comments
 (0)