-
Notifications
You must be signed in to change notification settings - Fork 25k
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
Start on custom whitelists for Painless #23563
Conversation
We'd like to be able to support context-sensitive whitelists in Painless but we can't now because the whitelist is a static thing. This begins to de-static the whitelist, in particular removing the static keyword from `Definition#getRuntimeClass` and plumbing the static instance into the appropriate spots as though it weren't static. Once we de-static all the methods we should be able to fairly simply build context-sensitive whitelists. The only "fun" bit of this is that I added another layer in the chain of methods that bootstraps `def` calls. Instead of running `invokedynamic` directly on `DefBootstrap` we now `invokedynamic` `$bootstrapDef` on the script itself loads the `Definition` that the script was compiled against and then calls `DefBootstrap`.
@@ -30,14 +30,17 @@ | |||
import org.elasticsearch.test.ESTestCase; | |||
|
|||
public class DefBootstrapTests extends ESTestCase { | |||
private final Definition definition = Definition.INSTANCE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this in the tests instead of using Definition.INSTANCE
everywhere because I think we'll remove Definition.INSTANCE
when we're done making context sensitive whitelists.
@jdconrad I mentioned this to you earlier today though I wasn't particularly clear. I figured this was one of those times when it is easier to look at code then try to describe it. What do you think about this as a first step towards context sensitive whitelists? |
@jdconrad, what do you think of this as an approach? The next step would be to un-static the rest of Definition. The step after would be to have a look at custom definitions. |
@nik9000 Sorry, meant to get to this last week. I see what you mean now when you mentioned all the additional plumbing going everywhere which is a bummer, but I don't see a good way around it either. No matter what happens the information for the 'binding' will have to be passed in somewhere, so it may as well be the Definition that specifies this. So far, this does indeed seem like the correct approach. I'll be curious to see how it turns once more is completed. |
Do you want me to push merge this as is or de-static all the stuff and then review? I like doing this partially but if you're not sure if this shows the way to go well enough then I will keep going. |
Also, don't worry about reviews taking time. It is all good! |
@@ -216,6 +220,19 @@ public void write() { | |||
visitor.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, classBase, classInterfaces); | |||
visitor.visitSource(Location.computeSourceName(name, source), null); | |||
|
|||
// Write the a method to bootstrap def calls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this have to be in bytecode? Why not make this whole method part of the PainlessScript?
Edit: Is this to avoid passing the Definition around? Because I think it'll need to be passed into the nodes in some way for compile-time method/field look ups?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do it this way because def
is always going to need getRuntimeClass
(or something like it) to be specific for each generated class. So each generated class needs its own static reference to the appropriate Definition
. Lifting the method to PainlessScript
would require resolving the Definition
with reflection or a method reference or something.
I could also play around with making the bootstrap method non-static. If I did that I could indeed move this to PainlessScript
. I didn't think that'd work when I was working on it the first time but now I think it might. Do you think I should have a look at that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look like it can be a non-static method given the order of the required arguments, and the reason for this method is explained below. Thanks.
I'd like to see a bit more please. It's so much harder to ask for changes if part of the code is already in. |
🤘 |
After looking more closely at the DefBootstrap method modifications, I'm a bit surprised this works based on the spec for invokedynamic (https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic). Sure seems like it would be illegal to have Definition as the first argument of the bootstrap method (possibly as an argument at all since it's not a constant). |
I'll have a deeper look soon. |
Oh! That works because we no longer call |
I understand. Thanks for the explanation. |
Removing review as I'll be doing more work on this before the next round of review. |
I chose to put `Definition` into `Locals` so I didn't have to change the signature of all the `analyze` methods. I could have do it another way, but that seems ok for now.
@jdconrad I de- I chose to pass Do you think it is OK to stop here and do the actual custom |
@nik9000 I kind of figured that Definition would end up as part of Locals since it's the least disruptive way to get the necessary plumbing in there. Seems like a reasonable stopping place, and I'll try to take a good look at this review tomorrow (I have test triage today). |
Thanks!
Enjoy! |
@nik9000 Sorry for the delay here. I know I still owe you a review -- haven't forgotten, will definitely happen this week. I got caught up in other issues. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Thanks for the review @jdconrad! I'll try and merge next week. I have a
ton of test failures waiting for me when I get back on Monday. At this
point I'd be surprised if I do anything other than debug those failures for
a few days. That reindex one is sneaky!
…On Fri, Apr 14, 2017, 12:53 PM Jack Conradson ***@***.***> wrote:
***@***.**** approved this pull request.
LGTM.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#23563 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AANLosHKutRJOyEOPV14MP_WZOgxZzh8ks5rv6RvgaJpZM4Ma47n>
.
|
We'd like to be able to support context-sensitive whitelists in Painless but we can't now because the whitelist is a static thing. This begins to de-static the whitelist, in particular removing the static keyword from most of the methods on `Definition` and plumbing the static instance into the appropriate spots as though it weren't static. Once we de-static all the methods we should be able to fairly simply build context-sensitive whitelists. The only "fun" bit of this is that I added another layer in the chain of methods that bootstraps `def` calls. Instead of running `invokedynamic` directly on `DefBootstrap` we now `invokedynamic` `$bootstrapDef` on the script itself loads the `Definition` that the script was compiled against and then calls `DefBootstrap`. I chose to put `Definition` into `Locals` so I didn't have to change the signature of all the `analyze` methods. I could have do it another way, but that seems ok for now.
We'd like to be able to support context-sensitive whitelists in
Painless but we can't now because the whitelist is a static thing.
This begins to de-static the whitelist, in particular removing
the static keyword from
Definition#getRuntimeClass
and plumbingthe static instance into the appropriate spots as though it weren't
static. Once we de-static all the methods we should be able to
fairly simply build context-sensitive whitelists.
The only "fun" bit of this is that I added another layer in the
chain of methods that bootstraps
def
calls. Instead of runninginvokedynamic
directly onDefBootstrap
we nowinvokedynamic
$bootstrapDef
on the script itself loads theDefinition
thatthe script was compiled against and then calls
DefBootstrap
.