Skip to content

Commit

Permalink
Fix search for bind control records
Browse files Browse the repository at this point in the history
It is possible that the bind control record is in a stack segment prior
to the one that a frame is allocated in. In code that recurses enough to
trigger multiple stack segments, this situation may occur, and could
lead to multiple dispatch of candidates with `where` clauses and similar
wrongly reporting an error instead of continuing to the next candidate.
  • Loading branch information
jnthn committed Sep 8, 2021
1 parent 0fed320 commit 5d43eea
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/core/args.c
Expand Up @@ -1081,6 +1081,8 @@ void MVM_args_bind_failed(MVMThreadContext *tc, MVMDispInlineCacheEntry **ice_pt
* bind failure handler. This is determined by if there is a bind failure
* frame under us on the callstack in a fresh state. */
MVMCallStackRecord *under_us = tc->stack_top->prev;
while (under_us && under_us->kind == MVM_CALLSTACK_RECORD_START_REGION)

This comment has been minimized.

Copy link
@mlschroe

mlschroe Sep 10, 2021

This looks a bit questionable. If under_us really can become NULL, the under_us->kind condition after the loop will segfault. So either the if statement needs a under_us && or the under_us && in the while loop can be removed.

This comment has been minimized.

Copy link
@jnthn

jnthn Sep 10, 2021

Author Member

Good catch, thank you. Rectified in 4bcc5a0.

under_us = under_us->prev;
if (under_us->kind == MVM_CALLSTACK_RECORD_BIND_CONTROL) {
MVMCallStackBindControl *control_record = (MVMCallStackBindControl *)under_us;
MVMBindControlState state = control_record->state;
Expand Down Expand Up @@ -1117,6 +1119,8 @@ void MVM_args_bind_failed(MVMThreadContext *tc, MVMDispInlineCacheEntry **ice_pt
* dispatch resumption. */
void MVM_args_bind_succeeded(MVMThreadContext *tc, MVMDispInlineCacheEntry **ice_ptr) {
MVMCallStackRecord *under_us = tc->stack_top->prev;
while (under_us && under_us->kind == MVM_CALLSTACK_RECORD_START_REGION)
under_us = under_us->prev;
if (under_us->kind == MVM_CALLSTACK_RECORD_BIND_CONTROL) {
MVMCallStackBindControl *control_record = (MVMCallStackBindControl *)under_us;
MVMBindControlState state = control_record->state;
Expand Down

0 comments on commit 5d43eea

Please sign in to comment.