diff options
-rw-r--r-- | erts/preloaded/src/prim_eval.S | 4 | ||||
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 8 |
2 files changed, 12 insertions, 0 deletions
diff --git a/erts/preloaded/src/prim_eval.S b/erts/preloaded/src/prim_eval.S index e4b1560517..900fda5d89 100644 --- a/erts/preloaded/src/prim_eval.S +++ b/erts/preloaded/src/prim_eval.S @@ -42,6 +42,10 @@ {label,3}. {loop_rec,{f,5},{x,0}}. {move,{y,1},{x,1}}. + %% Tell the validator that it's safe to pass the message as an argument, + %% as the match fun is "known" not to build a term with it, and the + %% loop_rec instruction has disabled the GC. + {'%', {remove_fragility, {x,0}}}. {call_fun,1}. {test,is_ne_exact,{f,4},[{x,0},{atom,nomatch}]}. remove_message. diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 63da5d44ba..6044c1bfab 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -476,6 +476,14 @@ valfun_1({'%', {type_info, Reg, Type}}, Vst) -> %% that Reg has a certain type, so that we can accept cross-function type %% optimizations. update_type(fun meet/2, Type, Reg, Vst); +valfun_1({'%', {remove_fragility, Reg}}, Vst) -> + %% This is a hack to make prim_eval:'receive'/2 work. + %% + %% Normally it's illegal to pass fragile terms as a function argument as we + %% have no way of knowing what the callee will do with it, but we know that + %% prim_eval:'receive'/2 won't leak the term, nor cause a GC since it's + %% disabled while matching messages. + remove_fragility(Reg, Vst); valfun_1({'%',_}, Vst) -> Vst; valfun_1({line,_}, Vst) -> |