Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move specialized execute method code into an external phase #51954

Merged
merged 10 commits into from
Feb 11, 2020

Conversation

jdconrad
Copy link
Contributor

@jdconrad jdconrad commented Feb 5, 2020

This change moves almost all of the customized code required to decorate the execute method into an external phase. This external phase operates only on the ir tree after the user tree has generated the initial ir tree from user specified code. The external phase uses ir nodes to create the necessary customized code instead of writing asm directly. This is a first example of modifying the ir tree to customize it specifically for Elasticsearch and leaves the ir nodes in a more generic state.

Another change required for this was to remove the notion of auto-return from the ir tree completely. The user tree is now responsible for generating appropriate ir tree nodes to support auto-return. This is the first example of divergent user and ir trees as the user tree is intended to be higher level while the ir tree is supposed to provide lower level translation into asm.

Relates to #49869
Relates to #51841

@jdconrad jdconrad added :Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >refactoring v8.0.0 labels Feb 5, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (:Core/Infra/Scripting)

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few general suggestions. Overall if it gets us closer to having less special cases I'm fine with this for now.

import java.util.Map;

/**
* This injects additional ir nodes required to for
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: to for -> for

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

callSubNode.addArgumentNode(unboundFieldNode);

for (Class<?> throwable : new Class<?>[] {
PainlessError.class, BootstrapMethodError.class, OutOfMemoryError.class, StackOverflowError.class, Exception.class}) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be a class constant, like ERRORS_TO_CATCH?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to change in future PRs so I would prefer to leave this for now.

}
}

protected DecorateExecutePhase() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be private, no need to construct right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


import static org.elasticsearch.painless.WriterConstants.CLASS_TYPE;

public class UnboundFieldNode extends ExpressionNode {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would MemberFieldNode be a better name here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and fixed.


if (name.equals(declarationNode.getName())) {
if (scriptRoot.getUsedVariables().contains(name)) {
UnboundCallNode unboundCallNode = new UnboundCallNode();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should rename this to MemberCallNode? The meaning of unbound is unclear

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and fixed.

* that are used and adds additional sandboxing by wrapping
* the main "execute" block with several exceptions.
*/
public class DecorateExecutePhase {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really decorating execute (well the try/catch is, but it's still not decorating, it's wrapping in that case?). In the other case we have variables being converted to this.getXXX() calls...they seem unrelated, maybe they should be separate classes? In both these cases these seem to be things we need for correctness in the IR tree, so to me should be part of the creation of the IR tree, rather than phases operating on it. But I also appreciate this is just a step towards the overarching refactor, so if this frees up space to move towards that future, I'm fine with this as is for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed this ScriptInjectionPhase for now. But as we discussed this will change significantly, and I agree with your assessments of correctness. I would like to note that my line of thought was the user tree is what requires semantic checking and the ir tree is semantically correct (always other than bugs). I will also consider correctness moving forward in that the ir tree should always be in a state that can be written to ASM as any given time. We will get there, but there's a bunch more work in between to clean up enough to make those changes.

@jdconrad
Copy link
Contributor Author

@rjernst Thank you for the review. I hope I've adequately addressed your concerns, and I think we continue to be on the same page for the end goals of these refactors. Will merge as soon as CI passes.

@jdconrad jdconrad merged commit 026474d into elastic:master Feb 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >refactoring v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants