Skip to content

Commit

Permalink
FIXED: проблема со специализацией замыканий (#251, #359)
Browse files Browse the repository at this point in the history
Ранее специализация замыкания {{ &F CONTENT }} осуществлялась как
специализация фиктивного вызова <F CONTENT e.@>. Оптимизатор строил новый
вызов <F@1 CONTENT′ e.@>, из которого восстанавливалось замыкание
{{ &F@1 CONTENT′ }}.

Добавлять и удалять фиктивную переменную e.@ было безопасно, т.к. она была
в позиции динамического параметра, позиция параметра не менялась (оставалась
последней) и во внутрь функции она не протекала.

Теперь же при специализации это имя может протечь внутрь экземпляра,
внутри экземпляра может оказаться другое замыкание, в контексте которого
будет переменная e.@. Добавление e.@ в конец вызовет конфликт имён.

----

В коде есть некоторый костыль, который проистекает из отсутствия поддержки
подавления предупреждений. Исходники намеренно собираются с -Werror,
а в данном коде было бы разумно явно добавить «подозрительную» (#290)
повторную переменную. Пришлось достигать эту проверку более громоздким
куском исходного кода.
  • Loading branch information
Mazdaywik committed Jun 26, 2021
1 parent c1ae85c commit b73aa8f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
27 changes: 27 additions & 0 deletions autotests/opt-tree-spec15.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
* TREE

$ENTRY Go {
/* empty */
= <LoadAST (Config) R5 'srcname.ref'> : (R5 (Config) 'srcname.ref')
= <<LoadAST (Config) RSL 'srcname.rsl'>> : s.Fn
= <s.Fn True> : (R5 (Config) 'srcname-decompiled.ref')
= <s.Fn False> : (FileRowCol (1 1) 'srcname-decompiled.ref')
= /* empty */;
}

LoadAST {
t.Config R5 e.SrcName = (R5 t.Config e.SrcName);

t.Config RSL e.SrcName
= e.SrcName : e.BaseName '.rsl'
= e.BaseName '-decompiled.ref' : e.DecompiledName
= (FileRowCol (1 1) e.DecompiledName) : t.ErrorPos
= {
/* empty */
= <LoadAST t.Config R5 e.DecompiledName> : t.AST
= {
True = t.AST;
False = t.ErrorPos;
};
}
}
19 changes: 17 additions & 2 deletions src/compiler/OptTree-Spec.ref
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,27 @@ SpecTerm {
}
: s.TrySpecCall

= <ExtractVariables-Expr e.ClosureContent> : e.UsedVars
= <NewVarName (e.UsedVars) 'eClosureArg'> : (e._) e.eClosureArg
= <s.TrySpecCall
(e.SpecInfo (e.Histories) (e.History) (e.NewFunctions))
(CallBrackets e.ClosureContent (Var 'e@'))
(CallBrackets e.ClosureContent (Var e.eClosureArg))
>
: (e.SpecInfo^ (e.Histories^) (e.History^) (e.NewFunctions^))
(CallBrackets e.ClosureContent^ (Var 'e@'))
(CallBrackets e.ClosureContent^ (Var e.eClosureArgOut))

/*
Проверка на то, что e.eClosureArg и e.eClosureArgOut равны. Проверить
через повторную переменную нельзя, т.к. стоит режим -Werror для
сборки исходников.
TODO: исправить при реализации подавления предупреждений.
*/
= e.eClosureArgOut
: {
e.eClosureArg = /* пусто */;
e._ = <{}>
}
: /* пусто */

= e.ClosureContent
: {
Expand Down

0 comments on commit b73aa8f

Please sign in to comment.