Merge pull request #18338 from uschindler/painless_arrayindextype
painless: build descriptor of array and field load/store in code
This commit is contained in:
commit
8f82fa9a58
|
@ -61,15 +61,6 @@ public final class WriterConstants {
|
|||
new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(DefBootstrap.class),
|
||||
"bootstrap", DEF_BOOTSTRAP_TYPE.toMethodDescriptorString());
|
||||
|
||||
public final static String DEF_DYNAMIC_LOAD_FIELD_DESC =
|
||||
MethodType.methodType(Object.class, Object.class).toMethodDescriptorString();
|
||||
public final static String DEF_DYNAMIC_STORE_FIELD_DESC =
|
||||
MethodType.methodType(void.class, Object.class, Object.class).toMethodDescriptorString();
|
||||
public final static String DEF_DYNAMIC_ARRAY_LOAD_DESC =
|
||||
MethodType.methodType(Object.class, Object.class, Object.class).toMethodDescriptorString();
|
||||
public final static String DEF_DYNAMIC_ARRAY_STORE_DESC =
|
||||
MethodType.methodType(void.class, Object.class, Object.class, Object.class).toMethodDescriptorString();
|
||||
|
||||
public final static Method DEF_NOT_CALL = getAsmMethod(Object.class, "not", Object.class);
|
||||
public final static Method DEF_NEG_CALL = getAsmMethod(Object.class, "neg", Object.class);
|
||||
public final static Method DEF_MUL_CALL = getAsmMethod(Object.class, "mul", Object.class, Object.class);
|
||||
|
|
|
@ -23,11 +23,10 @@ import org.elasticsearch.painless.CompilerSettings;
|
|||
import org.elasticsearch.painless.Definition;
|
||||
import org.elasticsearch.painless.DefBootstrap;
|
||||
import org.elasticsearch.painless.Variables;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.GeneratorAdapter;
|
||||
|
||||
import static org.elasticsearch.painless.WriterConstants.DEF_BOOTSTRAP_HANDLE;
|
||||
import static org.elasticsearch.painless.WriterConstants.DEF_DYNAMIC_ARRAY_LOAD_DESC;
|
||||
import static org.elasticsearch.painless.WriterConstants.DEF_DYNAMIC_ARRAY_STORE_DESC;
|
||||
|
||||
/**
|
||||
* Represents an array load/store or shortcut on a def type. (Internal only.)
|
||||
|
@ -45,8 +44,8 @@ final class LDefArray extends ALink {
|
|||
|
||||
@Override
|
||||
ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) {
|
||||
index.expected = definition.objectType;
|
||||
index.analyze(settings, definition, variables);
|
||||
index.expected = index.actual;
|
||||
index = index.cast(settings, definition, variables);
|
||||
|
||||
after = definition.defType;
|
||||
|
@ -61,14 +60,16 @@ final class LDefArray extends ALink {
|
|||
|
||||
@Override
|
||||
void load(final CompilerSettings settings, final Definition definition, final GeneratorAdapter adapter) {
|
||||
final String desc = Type.getMethodDescriptor(after.type, definition.defType.type, index.actual.type);
|
||||
adapter.visitInvokeDynamicInsn(
|
||||
"arrayLoad", DEF_DYNAMIC_ARRAY_LOAD_DESC, DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.ARRAY_LOAD });
|
||||
|
||||
"arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.ARRAY_LOAD });
|
||||
}
|
||||
|
||||
@Override
|
||||
void store(final CompilerSettings settings, final Definition definition, final GeneratorAdapter adapter) {
|
||||
final String desc = Type.getMethodDescriptor(definition.voidType.type, definition.defType.type,
|
||||
index.actual.type, definition.defType.type);
|
||||
adapter.visitInvokeDynamicInsn(
|
||||
"arrayStore", DEF_DYNAMIC_ARRAY_STORE_DESC, DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.ARRAY_STORE });
|
||||
"arrayStore", desc, DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.ARRAY_STORE });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ final class LDefCall extends ALink {
|
|||
|
||||
signature.append(')');
|
||||
// return value
|
||||
signature.append(definition.defType.type.getDescriptor());
|
||||
signature.append(after.type.getDescriptor());
|
||||
|
||||
adapter.visitInvokeDynamicInsn(name, signature.toString(), DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.METHOD_CALL });
|
||||
}
|
||||
|
|
|
@ -23,11 +23,10 @@ import org.elasticsearch.painless.CompilerSettings;
|
|||
import org.elasticsearch.painless.Definition;
|
||||
import org.elasticsearch.painless.DefBootstrap;
|
||||
import org.elasticsearch.painless.Variables;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.GeneratorAdapter;
|
||||
|
||||
import static org.elasticsearch.painless.WriterConstants.DEF_BOOTSTRAP_HANDLE;
|
||||
import static org.elasticsearch.painless.WriterConstants.DEF_DYNAMIC_LOAD_FIELD_DESC;
|
||||
import static org.elasticsearch.painless.WriterConstants.DEF_DYNAMIC_STORE_FIELD_DESC;
|
||||
|
||||
/**
|
||||
* Represents a field load/store or shortcut on a def type. (Internal only.)
|
||||
|
@ -57,11 +56,13 @@ final class LDefField extends ALink {
|
|||
|
||||
@Override
|
||||
void load(final CompilerSettings settings, final Definition definition, final GeneratorAdapter adapter) {
|
||||
adapter.visitInvokeDynamicInsn(value, DEF_DYNAMIC_LOAD_FIELD_DESC, DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.LOAD });
|
||||
final String desc = Type.getMethodDescriptor(after.type, definition.defType.type);
|
||||
adapter.visitInvokeDynamicInsn(value, desc, DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.LOAD });
|
||||
}
|
||||
|
||||
@Override
|
||||
void store(final CompilerSettings settings, final Definition definition, final GeneratorAdapter adapter) {
|
||||
adapter.visitInvokeDynamicInsn(value, DEF_DYNAMIC_STORE_FIELD_DESC, DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.STORE });
|
||||
final String desc = Type.getMethodDescriptor(definition.voidType.type, definition.defType.type, definition.defType.type);
|
||||
adapter.visitInvokeDynamicInsn(value, desc, DEF_BOOTSTRAP_HANDLE, new Object[] { DefBootstrap.STORE });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,9 +175,15 @@ public class WhenThingsGoWrongTests extends ScriptTestCase {
|
|||
});
|
||||
}
|
||||
|
||||
public void testDynamicWrongArgs() {
|
||||
public void testDynamicArrayWrongIndex() {
|
||||
expectThrows(WrongMethodTypeException.class, () -> {
|
||||
exec("def x = new ArrayList(); return x.get('bogus');");
|
||||
exec("def x = new long[1]; x[0]=1; return x['bogus'];");
|
||||
});
|
||||
}
|
||||
|
||||
public void testDynamicListWrongIndex() {
|
||||
expectThrows(WrongMethodTypeException.class, () -> {
|
||||
exec("def x = new ArrayList(); x.add('foo'); return x['bogus'];");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue