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

fix Issue 16301 - CTFE execution of opApply keeps wrong "this" context in foreach's body #6813

Closed
wants to merge 1 commit into from

Conversation

UplinkCoder
Copy link
Member

@UplinkCoder UplinkCoder commented May 19, 2017

Fixes issue 16301 by walking up the stack of previous this-pointers and looking for a match.
This will allow delegates to properly work at ctfe.

@mathias-lang-sociomantic
Copy link
Contributor

Please use a more descriptive title when submitting P.R., so that people watching this repo don't have to open the P.R. to know if it's of interest to them.
Also this lacks a test-case.

@dlang-bot
Copy link
Contributor

Fix Bugzilla Description
16301 CTFE execution of opApply keeps wrong "this" context in foreach's body

@UplinkCoder
Copy link
Member Author

@mathias-lang-sociomantic
I added a testcase.

@UplinkCoder
Copy link
Member Author

@WalterBright
I am not sure if the code in issue 16301 only works by accident.
Are delegates required to capture the nearest this pointer if there is no function-local context ?
It seems like an implementation detail ...

@UplinkCoder UplinkCoder changed the title fix Issue 16301 fix Issue 16301 [don't merge yet] May 19, 2017
@UplinkCoder UplinkCoder force-pushed the fix_16301 branch 2 times, most recently from 097b742 to 6a15ae1 Compare May 19, 2017 15:16
@UplinkCoder UplinkCoder changed the title fix Issue 16301 [don't merge yet] fix Issue 16301 May 19, 2017
@WalterBright WalterBright changed the title fix Issue 16301 fix Issue 16301 - CTFE execution of opApply keeps wrong "this" context in foreach's body May 19, 2017
@WalterBright
Copy link
Member

When doing bugfix PRs, please have the subject match the bugzilla entry, prefixed with "fix". I already fixed this one.

@wilzbach
Copy link
Member

wilzbach commented May 19, 2017

When doing bugfix PRs, please have the subject match the bugzilla entry, prefixed with "fix". I already fixed this one.

The same goes for the commit messages...

@WalterBright
Copy link
Member

fix Issue 16301 [don't merge yet]

I added the [Needs Work] tag instead.

@UplinkCoder
Copy link
Member Author

@WalterBright I think the work is done.
You can remove the tag if you find the code agreeable.

@yebblies
Copy link
Member

There is almost certainly matching code in glue/e2ir/etc. Can that be re-used somehow, or can the context be cached during semantic? This will ensure the lookup has the same result at runtime and ctfe.

@UplinkCoder
Copy link
Member Author

@yebblies I had a look at e2ir and it add a negative offset to the stack-ptr, to walk up the stack-frames, we cannot do that in ctfe.
The code I have here comes closest to what e2ir does

@yebblies
Copy link
Member

But isn't that pretty much what we're doing here? We do have a stack and we can index with a negative offset to our current frame...?

Your code here to walk up the scope chain and find the right 'this', which I assume e2ir also does, could that be moved into semantic somewhere? Or does semantic already do this (for semantic checking) in which case can it save the result somewhere so we don't have to recompute?

@UplinkCoder
Copy link
Member Author

UplinkCoder commented May 22, 2017

@yebblies the this we want to find is a "runtime" value.
therefore we cannot cannot cache this in semantic.
Maybe we could pre-compute how many stack frames we have to walk up to get at the variable but I am not sure if adding that complexity is warranted.

// a this that has a matching type.
// https://issues.dlang.org/showbug.cgi?id=16301
size_t stackOffset = ctfeStack.savedThis.dim;
while(stackOffset && (!result || !result.type.equals(e.type)))
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this essentially implementing a dynamic scoping approach instead of a lexical scoping one?

If ctfeStack is the call stack - this sounds incorrect in the general case.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's right, ctfeStack is the call stack.
However if a there is a closure it must have been created by a function call, therefore
The aggregate's this must be found and will be the same.
If you look at e2ir's closure handling, it's doing the same thing.
Lexical scope does not matter it just happens to be the same.

@UplinkCoder
Copy link
Member Author

@EyalIO has proven this unsound.
Back to the drawing board.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants