Inlining depends on argument's name

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Inlining depends on argument's name

wvxvw
Hello list.
My friend (BlooDHounD) http://www.blooddy.by/en/ has stumbled over interesting behavior in method inlining. This is what he had found:

If you have different names for the argument and the variable, then the argument is passed by value (you will see 0 in trace).
      static function main() {
          var i:UInt = 0;
          inc( i );
          inc( i );
          inc( i );
          trace( i );
     }

     static inline function inc(_i:UInt):Void {
          _i++;
     }

However, if the argument name and the variable name are the same, then the reference will be used. Thus trace will show 3.

        static function main() {
          var i:UInt = 0;
          inc( i );
          inc( i );
          inc( i );
          trace( i );
     }

     static inline function inc(i:UInt):Void {
          i++;
     }

We believe this is a bug, or, maybe this behavior wasn't intended, (I couldn't find any reference to it). However, this is a really cool feature! But if you are about to keep it, it would be better to use special syntax for it, rather than relying on name collision. For example, in PHP you can prefix a variable with & to show this is the reference and not the value.

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

Mark de Bruijn | Dykam
I remember this, and what I actually see happening is that it is inlined literally, and function argument become variable declarations.
--
Mark


On Thu, Jul 22, 2010 at 2:56 PM, Oleg Sivokon <[hidden email]> wrote:
Hello list.
My friend (BlooDHounD) http://www.blooddy.by/en/ has stumbled over interesting behavior in method inlining. This is what he had found:

If you have different names for the argument and the variable, then the argument is passed by value (you will see 0 in trace).
      static function main() {
          var i:UInt = 0;
          inc( i );
          inc( i );
          inc( i );
          trace( i );
     }

     static inline function inc(_i:UInt):Void {
          _i++;
     }

However, if the argument name and the variable name are the same, then the reference will be used. Thus trace will show 3.

        static function main() {
          var i:UInt = 0;
          inc( i );
          inc( i );
          inc( i );
          trace( i );
     }

     static inline function inc(i:UInt):Void {
          i++;
     }

We believe this is a bug, or, maybe this behavior wasn't intended, (I couldn't find any reference to it). However, this is a really cool feature! But if you are about to keep it, it would be better to use special syntax for it, rather than relying on name collision. For example, in PHP you can prefix a variable with & to show this is the reference and not the value.

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

tommedema
In reply to this post by wvxvw
This sounds like a serious bug

2010/7/22 Oleg Sivokon <[hidden email]>
Hello list.
My friend (BlooDHounD) http://www.blooddy.by/en/ has stumbled over interesting behavior in method inlining. This is what he had found:

If you have different names for the argument and the variable, then the argument is passed by value (you will see 0 in trace).
      static function main() {
          var i:UInt = 0;
          inc( i );
          inc( i );
          inc( i );
          trace( i );
     }

     static inline function inc(_i:UInt):Void {
          _i++;
     }

However, if the argument name and the variable name are the same, then the reference will be used. Thus trace will show 3.

        static function main() {
          var i:UInt = 0;
          inc( i );
          inc( i );
          inc( i );
          trace( i );
     }

     static inline function inc(i:UInt):Void {
          i++;
     }

We believe this is a bug, or, maybe this behavior wasn't intended, (I couldn't find any reference to it). However, this is a really cool feature! But if you are about to keep it, it would be better to use special syntax for it, rather than relying on name collision. For example, in PHP you can prefix a variable with & to show this is the reference and not the value.

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

Nicolas Cannasse
In reply to this post by wvxvw
Oleg Sivokon a écrit :
> Hello list.
> My friend (BlooDHounD) http://www.blooddy.by/en/ has stumbled over
> interesting behavior in method inlining. This is what he had found:

Hi,

Which version of haXe are you using ? This should be fixed already for a
long time and I can't reproduce with SVN version.

Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

wvxvw
The version used is 2.05.
However, please, this functionality was very useful in some cases... can it remain somehow in a different form? This actually let my friend improve the processing speed of the JPEG encoder quite significantly. It would be cool if it remained somehow...
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

Mark de Bruijn | Dykam
I don' t think fixing this issue will slow down inlining, as variables are probably redefined again already anyway.
--
Mark


On Thu, Jul 22, 2010 at 3:24 PM, wvxvw <[hidden email]> wrote:

The version used is 2.05.
However, please, this functionality was very useful in some cases... can it
remain somehow in a different form? This actually let my friend improve the
processing speed of the JPEG encoder quite significantly. It would be cool
if it remained somehow...
--
View this message in context: http://haxe.1354130.n2.nabble.com/Inlining-depends-on-argument-s-name-tp5325199p5325295.html
Sent from the Haxe mailing list archive at Nabble.com.

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

wvxvw
In reply to this post by wvxvw
Sorry for the double post. I've just realized that this behavior is very similar to C# ref and out like in this example:

String foo = "foo";

void Bar( ref bar ) { bar += bar; }

Bar(ref foo); // foofoo

So, maybe allow for functions marked as inline prefix the arguments with "ref" and "out" as this functionality already exists, just wrap it into a better shape?
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

Nicolas Cannasse
In reply to this post by wvxvw
wvxvw a écrit :
> The version used is 2.05.

Right, looking at SVN it's been fixed on January 24, only a few days
after latest 2.05 release ;)

> However, please, this functionality was very useful in some cases... can it
> remain somehow in a different form? This actually let my friend improve the
> processing speed of the JPEG encoder quite significantly. It would be cool
> if it remained somehow...

Sorry but this is clearly a bug wrt inlining semantics and have to be fixed.

You can either pass an object and modify its fields, or return a value
in your inline function that will be the modified value.

Implemeting by ref arguments would be much more difficult, and actually
quite slow on most platforms.

Nicolas


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

wvxvw
In reply to this post by Mark de Bruijn | Dykam
Mark, yes it slows it. It will create an additional variable always, but this is not always what you want. In the worst scenario you will have to bind to another "dummy" variable and then rebind it back to the variable you wanted to have the value. Here's just another example of how "out" may be used:

String foo;
Int32 bar;

Int32 Bar(out theString) { out = "foo"; return out.Length; }

bar = Bar(out foo);
// bar = 3, foo = "foo"

This is a much better workflow then "yield'ing" if you want a function to return multiple values.
Reply | Threaded
Open this post in threaded view
|

Re: Inlining depends on argument's name

wvxvw
In reply to this post by Nicolas Cannasse
Ouch, that had to be:

Int32 Bar(out theString) { theString = "foo"; return out.Length; }

Regarding multiple platforms... What I was suggesting is that ref/out would be applicable only to functions marked as inline, I do understand that it's difficult to have that functionality for every function on platforms that don't have it. As the compiler will be generating the code, it will have to discard the argument marked as "ref" or "out" and reuse the variable declared in the calling function. If I can make an assumption, this must be the way it worked before it was fixed.