<feed xmlns='http://www.w3.org/2005/Atom'>
<title>otp.git/lib/compiler/test, branch OTP-21.0</title>
<subtitle>Mirror of Erlang/OTP repository.
</subtitle>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/'/>
<entry>
<title>Update copyright year</title>
<updated>2018-06-18T12:51:18+00:00</updated>
<author>
<name>Henrik Nord</name>
<email>henrik@erlang.org</email>
</author>
<published>2018-06-18T12:51:18+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=5ca92e2eac1e84fd22f60e7abc3aa2b0ff1cb42b'/>
<id>5ca92e2eac1e84fd22f60e7abc3aa2b0ff1cb42b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>sys_core_fold: Fix name capture problem</title>
<updated>2018-06-04T08:41:21+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2018-06-04T04:14:19+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=7eb06ed5ac1687d38245db2e0aef2756cb43b1ae'/>
<id>7eb06ed5ac1687d38245db2e0aef2756cb43b1ae</id>
<content type='text'>
sys_core_fold could do unsafe transformations on the
code from the old inliner (invoked using the compiler
option `{inline,[{F/A}]}` to request inlining of specific
functions).

To explain the bug, let's first look at an example that
sys_core_fold handles correctly. Consider this code:

    'foo'/2 =
        fun (Arg1,Arg2) -&gt;
          let &lt;B&gt; = Arg2
          in let &lt;A,B&gt; = &lt;B,Arg1&gt;
             in {A,B}

In this example, the lets can be completely eliminated,
since the arguments for the lets are variables (as opposed
to expressions). Since the variable B is rebound in the
inner let, `sys_core_fold` must take special care when
doing the substitutions.

Here is the correct result:

    'foo'/2 =
        fun (Arg1, Arg2) -&gt;
          {Arg2,Arg1}

Consider a slight modifictation of the example:

    'bar'/2 =
        fun (Arg1,Arg2) -&gt;
            let &lt;B&gt; = [Arg2]
            in let &lt;A,B&gt; = &lt;B,[Arg1]&gt;
               in {A,B}

Here some of the arguments for the lets are expressions, so
the lets must be kept. sys_core_fold does not handle this
example correctly:

    'bar'/2 =
        fun (Arg1,Arg2) -&gt;
          let &lt;B&gt; = [Arg2]
    	  in let &lt;B&gt; = [Arg1]
    	     in {B,B}

In the inner let, the variable A has been eliminated and
replaced with the variable B in the body (the first B in
the tuple). Since the B in the outer let is never used,
the outer let will be eliminated, giving:

    'bar'/2 =
        fun (Arg1,Arg2) -&gt;
    	  let &lt;B&gt; = [Arg1]
    	  in {B,B}

To handle this example correctly, sys_core_fold must
rename the variable B in the inner let like this to
avoid capturing B:

    'bar'/2 =
       fun (Arg1,Arg2) -&gt;
         let &lt;B&gt; = [Arg2]
         in let &lt;NewName&gt; = [Arg1]
            in {B,NewName}

(Note: The `v3_kernel` pass alreday handles those examples correctly
in case `sys_core_fold` has been disabled.)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
sys_core_fold could do unsafe transformations on the
code from the old inliner (invoked using the compiler
option `{inline,[{F/A}]}` to request inlining of specific
functions).

To explain the bug, let's first look at an example that
sys_core_fold handles correctly. Consider this code:

    'foo'/2 =
        fun (Arg1,Arg2) -&gt;
          let &lt;B&gt; = Arg2
          in let &lt;A,B&gt; = &lt;B,Arg1&gt;
             in {A,B}

In this example, the lets can be completely eliminated,
since the arguments for the lets are variables (as opposed
to expressions). Since the variable B is rebound in the
inner let, `sys_core_fold` must take special care when
doing the substitutions.

Here is the correct result:

    'foo'/2 =
        fun (Arg1, Arg2) -&gt;
          {Arg2,Arg1}

Consider a slight modifictation of the example:

    'bar'/2 =
        fun (Arg1,Arg2) -&gt;
            let &lt;B&gt; = [Arg2]
            in let &lt;A,B&gt; = &lt;B,[Arg1]&gt;
               in {A,B}

Here some of the arguments for the lets are expressions, so
the lets must be kept. sys_core_fold does not handle this
example correctly:

    'bar'/2 =
        fun (Arg1,Arg2) -&gt;
          let &lt;B&gt; = [Arg2]
    	  in let &lt;B&gt; = [Arg1]
    	     in {B,B}

In the inner let, the variable A has been eliminated and
replaced with the variable B in the body (the first B in
the tuple). Since the B in the outer let is never used,
the outer let will be eliminated, giving:

    'bar'/2 =
        fun (Arg1,Arg2) -&gt;
    	  let &lt;B&gt; = [Arg1]
    	  in {B,B}

To handle this example correctly, sys_core_fold must
rename the variable B in the inner let like this to
avoid capturing B:

    'bar'/2 =
       fun (Arg1,Arg2) -&gt;
         let &lt;B&gt; = [Arg2]
         in let &lt;NewName&gt; = [Arg1]
            in {B,NewName}

(Note: The `v3_kernel` pass alreday handles those examples correctly
in case `sys_core_fold` has been disabled.)
</pre>
</div>
</content>
</entry>
<entry>
<title>bs_match_SUITE: Add test of multiple matches</title>
<updated>2018-05-21T12:38:20+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2018-05-21T05:34:17+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=e1957dd0920276ea942002477a3317cd8d1e7b5e'/>
<id>e1957dd0920276ea942002477a3317cd8d1e7b5e</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #1802 from michalmuskala/map-is-key-bif</title>
<updated>2018-05-07T08:30:22+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bgustavsson@gmail.com</email>
</author>
<published>2018-05-07T08:30:22+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=7a19de1bf0eb863e0d0febf7e7e5e555c8628575'/>
<id>7a19de1bf0eb863e0d0febf7e7e5e555c8628575</id>
<content type='text'>
Introduce is_map_key/2 guard BIF

OTP-15037
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Introduce is_map_key/2 guard BIF

OTP-15037
</pre>
</div>
</content>
</entry>
<entry>
<title>Introduce is_map_key/2 guard BIF</title>
<updated>2018-04-29T15:03:43+00:00</updated>
<author>
<name>Michał Muskała</name>
<email>michal@muskala.eu</email>
</author>
<published>2018-04-27T10:40:07+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=5d0874a8f9fd617308d9024783db1e4e24268184'/>
<id>5d0874a8f9fd617308d9024783db1e4e24268184</id>
<content type='text'>
This complements the `map_get/2` guard BIF introduced in #1784.

Rationale.

`map_get/2` allows accessing map fields in guards, but it might be
problematic in more complex guard expressions, for example:

foo(X) when map_get(a, X) =:= 1 or is_list(X) -&gt; ...

The `is_list/1` part of the guard could never succeed since the
`map_get/2` guard would fail the whole guard expression. In this
situation, this could be solved by using `;` instead of `or` to separate
the guards, but it is not possible in every case.

To solve this situation, this PR proposes a `is_map_key/2` guard that
allows to check if a map has key inside a guard before trying to access
that key. When combined with `is_map/1` this allows to construct a
purely boolean guard expression testing a value of a key in a map.

Implementation.

Given the use case motivating the introduction of this function, the PR
contains compiler optimisations that produce optimial code for the
following guard expression:

foo(X) when is_map(X) and is_map_key(a, X) and map_get(a, X) =:= 1 -&gt; ok;
foo(_) -&gt; error.

Given all three tests share the failure label, the `is_map_key/2` and
`is_map/2` tests are optimised away.

As with `map_get/2` the `is_map_key/2` BIF is allowed in match specs.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This complements the `map_get/2` guard BIF introduced in #1784.

Rationale.

`map_get/2` allows accessing map fields in guards, but it might be
problematic in more complex guard expressions, for example:

foo(X) when map_get(a, X) =:= 1 or is_list(X) -&gt; ...

The `is_list/1` part of the guard could never succeed since the
`map_get/2` guard would fail the whole guard expression. In this
situation, this could be solved by using `;` instead of `or` to separate
the guards, but it is not possible in every case.

To solve this situation, this PR proposes a `is_map_key/2` guard that
allows to check if a map has key inside a guard before trying to access
that key. When combined with `is_map/1` this allows to construct a
purely boolean guard expression testing a value of a key in a map.

Implementation.

Given the use case motivating the introduction of this function, the PR
contains compiler optimisations that produce optimial code for the
following guard expression:

foo(X) when is_map(X) and is_map_key(a, X) and map_get(a, X) =:= 1 -&gt; ok;
foo(_) -&gt; error.

Given all three tests share the failure label, the `is_map_key/2` and
`is_map/2` tests are optimised away.

As with `map_get/2` the `is_map_key/2` BIF is allowed in match specs.
</pre>
</div>
</content>
</entry>
<entry>
<title>beam_validator: Verify Y registers in exception-causing instructions</title>
<updated>2018-04-27T08:20:41+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2018-04-26T20:23:04+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=84150137640481ac139325bf8cc665dd47fca95c'/>
<id>84150137640481ac139325bf8cc665dd47fca95c</id>
<content type='text'>
When an exception is handled, the stack will be scanned. Therefore
all Y registers must be initialized.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When an exception is handled, the stack will be scanned. Therefore
all Y registers must be initialized.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #1797 from bjorng/bjorn/compiler/fold-apply/ERL-614</title>
<updated>2018-04-26T08:37:48+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bgustavsson@gmail.com</email>
</author>
<published>2018-04-26T08:37:48+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=b22051714857713e0f4f43f77ea02ec50532b2df'/>
<id>b22051714857713e0f4f43f77ea02ec50532b2df</id>
<content type='text'>
Rewrite a call of a literal external fun to a direct call

OTP-15044
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Rewrite a call of a literal external fun to a direct call

OTP-15044
</pre>
</div>
</content>
</entry>
<entry>
<title>Rewrite a call of a literal external fun to a direct call</title>
<updated>2018-04-25T10:51:21+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2018-04-23T13:20:43+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=bf84118febaae7857f12625584f33a649f79aeed'/>
<id>bf84118febaae7857f12625584f33a649f79aeed</id>
<content type='text'>
Rewrite calls such as:

    (fun erlang:abs/1)(-42)

to:

    erlang:abs(-42)

While we are at it, also add rewriting of apply/2 with a fixed
number of arguments to a direct call of the fun. For example:

    apply(F, [A,B])

would be rewritten to:

    F(A, B)

https://bugs.erlang.org/browse/ERL-614
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Rewrite calls such as:

    (fun erlang:abs/1)(-42)

to:

    erlang:abs(-42)

While we are at it, also add rewriting of apply/2 with a fixed
number of arguments to a direct call of the fun. For example:

    apply(F, [A,B])

would be rewritten to:

    F(A, B)

https://bugs.erlang.org/browse/ERL-614
</pre>
</div>
</content>
</entry>
<entry>
<title>sys_core_fold: Eliminate crash for map update in guard</title>
<updated>2018-04-25T08:38:59+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2018-04-25T05:41:49+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=6703828ea9085a4125812cfa47631d061032c514'/>
<id>6703828ea9085a4125812cfa47631d061032c514</id>
<content type='text'>
sys_core_fold would crash when attempting to optimize this code:

    t() when (#{})#{}-&gt;
        c.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
sys_core_fold would crash when attempting to optimize this code:

    t() when (#{})#{}-&gt;
        c.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'map-get-bif' of git://github.com/michalmuskala/otp</title>
<updated>2018-04-25T08:34:26+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2018-04-25T08:34:26+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=3682b7dab5a67843e54f0a93cc00a08b235c20c7'/>
<id>3682b7dab5a67843e54f0a93cc00a08b235c20c7</id>
<content type='text'>
* 'map-get-bif' of git://github.com/michalmuskala/otp:
  Introduce map_get guard-safe function

OTP-15037
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* 'map-get-bif' of git://github.com/michalmuskala/otp:
  Introduce map_get guard-safe function

OTP-15037
</pre>
</div>
</content>
</entry>
</feed>
