-
Notifications
You must be signed in to change notification settings - Fork 320
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
Access non-self arguments when widget annotations are computed #9410
Conversation
...ne/runtime-instrument-common/src/main/java/org/enso/interpreter/instrument/RuntimeCache.java
Outdated
Show resolved
Hide resolved
...e/runtime-instrument-common/src/main/java/org/enso/interpreter/service/ExecutionService.java
Outdated
Show resolved
Hide resolved
...ime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/InstrumentorBuiltin.java
Outdated
Show resolved
Hide resolved
Rejected: Send argument expressions, not valuesOnce @Frizi suggested to
Turns out that lazy evaluation of arguments isn't possible in this case. To evaluate arbitrary text in place one needs to run the whole program first and only when it reaches the requested point (and all local variables are available in stack frames) one can evaluate the expression. Looks like this is not how We could probably evaluate the widgets and visualizations in place while executing the whole program. However that would require bigger changes and possibly contradicts @hubertp is currently working on. |
distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso
Outdated
Show resolved
Hide resolved
distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso
Outdated
Show resolved
Hide resolved
There is 15 failures in: Fixed by 9c31cd4 |
_ -> annotation | ||
return_target err = err.payload.target | ||
Panic.catch Not_Invokable handler=return_target | ||
annotation value cache=cache |
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.
The cache
argument is "optional". If the function doesn't accept it, Not_Invokable
panic is raised. It is caught and the value that refused to accept cache
argument is returned instead. As a result it is not necessary to accept the cache
argument in dynamic dropdown functions.
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.
that is very subtle!
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.
Subtle, but tested!
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.
Great to have this. Can't wait to try building it out.
_ -> annotation | ||
return_target err = err.payload.target | ||
Panic.catch Not_Invokable handler=return_target | ||
annotation value cache=cache |
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.
that is very subtle!
private final Map<UUID, SoftReference<Object>> cache = new HashMap<>(); | ||
private final Map<UUID, Reference<Object>> cache = new HashMap<>(); | ||
private final Map<Object, UUID> valuesToKeys = new WeakHashMap<>(); | ||
private final Map<UUID, Reference<Object>> expressions = new HashMap<>(); |
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'm concerned that these new caches are not invalidated.
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.
The invalidation is happening in the compile job
Lines 372 to 383 in d665f4d
Seq( | |
CacheInvalidation( | |
CacheInvalidation.StackSelector.All, | |
invalidateExpressionsCommand, | |
Set(CacheInvalidation.IndexSelector.Weights) | |
), | |
CacheInvalidation( | |
CacheInvalidation.StackSelector.All, | |
invalidateStaleCommand, | |
Set(CacheInvalidation.IndexSelector.All) | |
) | |
) |
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.
Yes, these two new caches aren't invalidated. However that shouldn't matter much - both are using WeakReference
and as such they don't hold the referenced objects in memory more than cache
which uses SoftReference
- e.g. it is necessary to clean the cache
only, the valuesToKeys
and expressions
are going to be cleaned occasionally then by GC.
Btw. valuesToKeys
is a WeakHashMap
- e.g. the keys are hold by WeakReference
automatically. expressions
is using WeakReference
explicitly to hold the values.
I can write some tests, if necessary to prove the system is behaving correctly. Other than that there shall be no need to change the code.
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.
Test written in 63c0b20- we don't have an assertGC
test in the code base yet, we'll see how flaky it'll be. However the assertGC concept has been sufficiently used and tested already.
...ne/runtime-instrument-common/src/main/java/org/enso/interpreter/instrument/RuntimeCache.java
Show resolved
Hide resolved
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.
It's good enough for a merge, but ideally I'd like the collectArgumentNamesAndUuids
logic to be cleaned up a little. GUI team can do that after merging this PR though.
app/gui2/src/util/callTree.ts
Outdated
if (a instanceof ArgumentPlaceholder) { | ||
// pass thru | ||
} else { | ||
process(a.ast, a.argInfo?.name) |
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.
Instead of calculating index yourself, it should be passed here as a.index
. No need to pass MethodCallInfo
to this function.
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.
Alas a.index
isn't defined in the callTree.test.ts
as far as I can say. Maybe it is defined during runtime, but it is missing in the mocked environment. In any case, I can't change the code unless we want to remove the test. Probably better to have worse code with a test than better code without a test...
app/gui2/src/util/callTree.ts
Outdated
let index = 'self' === mci?.suggestion.arguments[0]?.name ? 1 : 0 | ||
for (const e of arr) { | ||
const notApplied = mci?.methodCall.notAppliedArguments ?? [] | ||
while (notApplied.indexOf(index) != -1) { | ||
index++ | ||
} | ||
if (e.uuid) { | ||
m['' + index] = e.uuid | ||
} | ||
const n: string | undefined = mci?.suggestion.arguments[index]?.name | ||
if (n && e.uuid) { | ||
m[n] = e.uuid | ||
} | ||
index++ | ||
} | ||
for (const e of arr) { | ||
if (e.name && e.uuid) { | ||
m[e.name] = e.uuid | ||
} | ||
} | ||
return m |
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.
Again, those separate loops are unnecessary. This whole logic can easily be moved into the process
function, directly writing to the m
output object. We have uuid, argument name and index all available there.
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.
Added some comments about names. @Frizi is doing main review.
app/gui2/src/util/callTree.ts
Outdated
} | ||
} | ||
} else { | ||
// ignore: process(args) |
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.
What does it mean? Why do we ignore? Should the process(args)
be called normally?
This else looks like it bears some important information, but I cannot decipher it here.
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.
Neither I. I don't know how to write a test for this case. What code one has to parse for FromInterpreterWithInfo
to not be ArgumentApplication
?
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.
AFAIK for example the call foo.bar
, where bar takes only self argument.
Let's move on, give libs guys access to |
Pull Request Description
Fixes #5629 by adding access to arguments with UUIDs when computing widget annotations.
Implementation Nodes
There are three parts to change:
on
annotation to accesscache
based on names of function argumentsExecutionService
Checklist
Please ensure that the following checklist has been satisfied before submitting the PR:
Scala,
Java,
style guides.
cache
argument in and check the behavior ofmake_join_condition_selector
: 6942ef5