# concatenation operator

- Thread: https://externals.io/message/60743
- Original archive: https://news-web.php.net/php.internals/60743
- Started by Adi Mutu on 2012-06-05T20:08:17+00:00
- Messages: 11
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #60743 — Adi Mutu — 2012-06-05T20:08:17+00:00

URL: https://externals.io/message/60743#60743

Hello,

Can somebody point me to where the concatenation operator is implemented ?  "." operator.

Thanks,

---

## #60744 — Felipe Pena — 2012-06-05T20:17:33+00:00

URL: https://externals.io/message/60743#60744 · In reply to: #60743

Hi,

2012/6/5 Adi Mutu <adi_mutu06@yahoo.com>:
>
>
> Hello,
>
> Can somebody point me to where the concatenation operator is implemented ?  "." operator.
>
> Thanks,

See http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_vm_def.h#133

-- 
Regards,
Felipe Pena

---

## #60776 — Adi Mutu — 2012-06-07T18:50:42+00:00

URL: https://externals.io/message/60743#60776 · In reply to: #60744

that's nice, but i haven't understood a thing...i know something about php core and php extensions, but nothing about the Zend engine specific. 
Can you point me to some resources on this topic?

Thanks,


________________________________
 From: Felipe Pena <felipensp@gmail.com>
To: Adi Mutu <adi_mutu06@yahoo.com> 
Cc: PHP Developers Mailing List <internals@lists.php.net> 
Sent: Tuesday, June 5, 2012 11:17 PM
Subject: Re: [PHP-DEV] concatenation operator
 
Hi,

2012/6/5 Adi Mutu <adi_mutu06@yahoo.com>:
>
>
> Hello,
>
> Can somebody point me to where the concatenation operator is implemented ?  "." operator.
>
> Thanks,

See http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_vm_def.h#133

-- 
Regards,
Felipe Pena

---

## #60777 — johannes@schlueters.de — 2012-06-07T19:44:21+00:00

URL: https://externals.io/message/60743#60777 · In reply to: #60776

> 
> that's nice, but i haven't understood a thing...i know something about
> php core and php extensions, but nothing about the Zend engine
> specific. 

The mentioned place is directly in the VM, which in general is harder to
understand, but well, it directs to the "concat_function" on
http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#1234

Knowing basic C should be enough to understand the code there. The
actual "algorithm" can also easily be guessed (allocate a buffer which
can hold both strings at once and copy them over,the code is a tiny bit
more complex as it tries tore use an existing buffer than allocating
something completely new)

The question is: What do you actually want to know?

> Can you point me to some resources on this topic?

Unfortunately not. The source is the best documentation we have for
that.

johannes

---

## #60778 — Adi Mutu — 2012-06-07T19:53:44+00:00

URL: https://externals.io/message/60743#60778 · In reply to: #60777

Ok Johannes, thanks for the answer. I'll try to look deeper. 
I basically just wanted to know what happens when you concatenate two strings? what emalloc/efree happens.

Also can you tell me if possible how to put a breakpoint to emalloc/efree which are executed only after all core functions are registered? because it takes like a million years like this and a million F8 presses...

Thanks.


________________________________
 From: Johannes Schlüter <johannes@schlueters.de>
To: Adi Mutu <adi_mutu06@yahoo.com> 
Cc: Felipe Pena <felipensp@gmail.com>; PHP Developers Mailing List <internals@lists.php.net> 
Sent: Thursday, June 7, 2012 10:44 PM
Subject: Re: [PHP-DEV] concatenation operator
 

> 
> that's nice, but i haven't understood a thing...i know something about
> php core and php extensions, but nothing about the Zend engine
> specific. 

The mentioned place is directly in the VM, which in general is harder to
understand, but well, it directs to the "concat_function" on
http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_operators.c#1234

Knowing basic C should be enough to understand the code there. The
actual "algorithm" can also easily be guessed (allocate a buffer which
can hold both strings at once and copy them over,the code is a tiny bit
more complex as it tries tore use an existing buffer than allocating
something completely new)

The question is: What do you actually want to know?

> Can you point me to some resources on this topic?

Unfortunately not. The source is the best documentation we have for
that.

johannes

---

## #60779 — johannes@schlueters.de — 2012-06-07T20:18:22+00:00

URL: https://externals.io/message/60743#60779 · In reply to: #60778

> Ok Johannes, thanks for the answer. I'll try to look deeper. 
> I basically just wanted to know what happens when you concatenate two
> strings? what emalloc/efree happens.

This depends. As always. As said what has to be done is one allocation
for the result value ... and then the zval magic, which depends on
refcount, references, ...

> Also can you tell me if possible how to put a breakpoint to
> emalloc/efree which are executed only after all core functions are
> registered? because it takes like a million years like this and a
> million F8 presses...

Depends on your debugger. Most allow conditional breakpoints or have a
breakpoint and while holding at some place add a few more ...

For such a question my preference is using DTrace (on Solaris, Mac or
BSD), something like this session:

        $ cat test.d
        #!/sbin/dtrace
        
        pid$target::concat_function:entry {
        	self->in_concat = 1;
        }
        
        pid$target::execute:return {
        	self->in_concat = 0;
        }
        
        pid$target::_emalloc:entry
        / self->in_concat /
        {
        	trace(arg0);
        	ustack();
        }
        
        pid$target::_erealloc:entry
        / self->in_concat /
        {
        	trace(arg0);
        	trace(arg1);
        	ustack();
        }
        
        $ cat test1.php
        <?php
        $a = "foo"; $b = "bar"; $a.$b;
        
        $ dtrace -s test.d -c 'php test1.php'
        dtrace: script 'test.d' matched 4 probes
        dtrace: pid 16406 has exited
        CPU     ID                    FUNCTION:NAME
          3 100372                   _emalloc:entry                 7
                      php`_emalloc
                      php`concat_function+0x270
                      php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
                      php`execute+0x3d9
                      php`dtrace_execute+0xe7
                      php`zend_execute_scripts+0xf5
                      php`php_execute_script+0x2e8
                      php`do_cli+0x864
                      php`main+0x6e2
                      php`_start+0x83
        
        $ cat test2.php
        <?php
        $a = 23; $b = "bar"; $a.$b;
        
        $ dtrace -s test.d -c 'php test2.php'
        dtrace: script 'test.d' matched 4 probes
        dtrace: pid 16425 has exited
        CPU     ID                    FUNCTION:NAME
          1 100373                  _erealloc:entry                 0               79
                      php`_erealloc
                      php`xbuf_format_converter+0x11ee
                      php`vspprintf+0x34
                      php`zend_spprintf+0x2f
                      php`_convert_to_string+0x174
                      php`zend_make_printable_zval+0x5ec
                      php`concat_function+0x3c
                      php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
                      php`execute+0x3d9
                      php`dtrace_execute+0xe7
                      php`zend_execute_scripts+0xf5
                      php`php_execute_script+0x2e8
                      php`do_cli+0x864
                      php`main+0x6e2
                      php`_start+0x83
        
          1 100372                   _emalloc:entry                 6
                      php`_emalloc
                      php`concat_function+0x270
                      php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
                      php`execute+0x3d9
                      php`dtrace_execute+0xe7
                      php`zend_execute_scripts+0xf5
                      php`php_execute_script+0x2e8
                      php`do_cli+0x864
                      php`main+0x6e2
                      php`_start+0x83
        
So, when having two constant strings there's a single malloc, in this
case allocating 7 bytes (strlen("foo")+strlen("bar")+1), if you have a
different type it has to be converted first ...


johannes

---

## #61048 — Adi Mutu — 2012-06-29T18:47:30+00:00

URL: https://externals.io/message/60743#61048 · In reply to: #60779

Hello,

Sorry for the late reply, I was away for a while......
I don't think I have dtrace because I'm on fedora.....but i'll research.

If i would want to set a breakpoint after php's initialization process, but right before the scripts execution, so that after that I can set breakpoints to emalloc and efree which are executed only during my scripts execution where should i set it? Hope the question was clear enough.....

dtrace related:
Why have you used 'execute:return' and not concat_function:return? What's with the execute function?


Thanks,
A.


________________________________
 From: Johannes Schlüter <johannes@schlueters.de>
To: Adi Mutu <adi_mutu06@yahoo.com> 
Cc: Felipe Pena <felipensp@gmail.com>; PHP Developers Mailing List <internals@lists.php.net> 
Sent: Thursday, June 7, 2012 11:18 PM
Subject: Re: [PHP-DEV] concatenation operator
 

> Ok Johannes, thanks for the answer. I'll try to look deeper. 
> I basically just wanted to know what happens when you concatenate two
> strings? what emalloc/efree happens.

This depends. As always. As said what has to be done is one allocation
for the result value ... and then the zval magic, which depends on
refcount, references, ...

> Also can you tell me if possible how to put a breakpoint to
> emalloc/efree which are executed only after all core functions are
> registered? because it takes like a million years like this and a
> million F8 presses...

Depends on your debugger. Most allow conditional breakpoints or have a
breakpoint and while holding at some place add a few more ...

For such a question my preference is using DTrace (on Solaris, Mac or
BSD), something like this session:

        $ cat test.d
        #!/sbin/dtrace
        
        pid$target::concat_function:entry {
            self->in_concat = 1;
        }
        
        pid$target::execute:return {
            self->in_concat = 0;
        }
        
        pid$target::_emalloc:entry
        / self->in_concat /
        {
            trace(arg0);
            ustack();
        }
        
        pid$target::_erealloc:entry
        / self->in_concat /
        {
            trace(arg0);
            trace(arg1);
            ustack();
        }
        
        $ cat test1.php
        <?php
        $a = "foo"; $b = "bar"; $a.$b;
        
        $ dtrace -s test.d -c 'php test1.php'
        dtrace: script 'test.d' matched 4 probes
        dtrace: pid 16406 has exited
        CPU     ID                    FUNCTION:NAME
          3 100372                   _emalloc:entry                 7
                      php`_emalloc
                      php`concat_function+0x270
                      php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
                      php`execute+0x3d9
                      php`dtrace_execute+0xe7
                      php`zend_execute_scripts+0xf5
                      php`php_execute_script+0x2e8
                      php`do_cli+0x864
                      php`main+0x6e2
                      php`_start+0x83
        
        $ cat test2.php
        <?php
        $a = 23; $b = "bar"; $a.$b;
        
        $ dtrace -s test.d -c 'php test2.php'
        dtrace: script 'test.d' matched 4 probes
        dtrace: pid 16425 has exited
        CPU     ID                    FUNCTION:NAME
          1 100373                  _erealloc:entry                 0               79
                      php`_erealloc
                      php`xbuf_format_converter+0x11ee
                      php`vspprintf+0x34
                      php`zend_spprintf+0x2f
                      php`_convert_to_string+0x174
                      php`zend_make_printable_zval+0x5ec
                      php`concat_function+0x3c
                      php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
                      php`execute+0x3d9
                      php`dtrace_execute+0xe7
                      php`zend_execute_scripts+0xf5
                      php`php_execute_script+0x2e8
                      php`do_cli+0x864
                      php`main+0x6e2
                      php`_start+0x83
        
          1 100372                   _emalloc:entry                 6
                      php`_emalloc
                      php`concat_function+0x270
                      php`ZEND_CONCAT_SPEC_CV_CV_HANDLER+0xcd
                      php`execute+0x3d9
                      php`dtrace_execute+0xe7
                      php`zend_execute_scripts+0xf5
                      php`php_execute_script+0x2e8
                      php`do_cli+0x864
                      php`main+0x6e2
                      php`_start+0x83
        
So, when having two constant strings there's a single malloc, in this
case allocating 7 bytes (strlen("foo")+strlen("bar")+1), if you have a
different type it has to be converted first ...


johannes

---

## #61050 — johannes@schlueters.de — 2012-06-29T21:36:57+00:00

URL: https://externals.io/message/60743#61050 · In reply to: #61048

> Sorry for the late reply, I was away for a while......
> I don't think I have dtrace because I'm on fedora.....but i'll
> research.

As said: Currently only on Solaris, MacOS and BSD. Oracle is porting
DTrace to Oracle Linux. RedHat created SystemTap which is similar, ut I
have never used it.

> If i would want to set a breakpoint after php's initialization
> process, but right before the scripts execution, so that after that I
> can set breakpoints to emalloc and efree which are executed only
> during my scripts execution where should i set it? Hope the question
> was clear enough.....

Depends on your view what "initialization" is. But execute() might be a
place which helps ... but even then you will see many things you're
probably not interested in. Only thing that helps is learning the code
structure and digging through it.

> dtrace related:
> Why have you used 'execute:return' and not concat_function:return?
> What's with the execute function?

That was a bug since I quickly edited an older script. In this case it
doesn't change the result.

johannes

---

## #61053 — Adi Mutu — 2012-06-30T10:53:25+00:00

URL: https://externals.io/message/60743#61053 · In reply to: #61050

By initialization i mean the latest point possible where I can set a breakpoint, but right before my scripts starts executing it's emalloc's or efree's.....

> but even then you will see many things you're probably not interested in

such as?......

> Only thing that helps is learning the code structure and digging through it.

Any hint/documentation to learn that?

Thanks.



________________________________
 From: Johannes Schlüter <johannes@schlueters.de>
To: Adi Mutu <adi_mutu06@yahoo.com> 
Cc: Felipe Pena <felipensp@gmail.com>; PHP Developers Mailing List <internals@lists.php.net> 
Sent: Saturday, June 30, 2012 12:36 AM
Subject: Re: [PHP-DEV] concatenation operator
 

> Sorry for the late reply, I was away for a while......
> I don't think I have dtrace because I'm on fedora.....but i'll
> research.

As said: Currently only on Solaris, MacOS and BSD. Oracle is porting
DTrace to Oracle Linux. RedHat created SystemTap which is similar, ut I
have never used it.

> If i would want to set a breakpoint after php's initialization
> process, but right before the scripts execution, so that after that I
> can set breakpoints to emalloc and efree which are executed only
> during my scripts execution where should i set it? Hope the question
> was clear enough.....

Depends on your view what "initialization" is. But execute() might be a
place which helps ... but even then you will see many things you're
probably not interested in. Only thing that helps is learning the code
structure and digging through it.

> dtrace related:
> Why have you used 'execute:return' and not concat_function:return?
> What's with the execute function?

That was a bug since I quickly edited an older script. In this case it
doesn't change the result.

johannes

---

## #61060 — johannes@schlueters.de — 2012-06-30T23:51:24+00:00

URL: https://externals.io/message/60743#61060 · In reply to: #61053

> 
> By initialization i mean the latest point possible where I can set a
> breakpoint, but right before my scripts starts executing it's
> emalloc's or efree's.....

Does "executing" include "compilation"? Does it include creating a stack
frame etc. for the "main" routine? ...

> > […]
> interested in
> 
> such as?......

Well, PHP is complex, it does quite a few things in order to run a
seemingly small script.

> > […]
> through it.
> 
> Any hint/documentation to learn that?

Use the source. ;-)

A bit more seriously: No, there's no good single place to look at, there
are different blogs etc looking at specific pieces in detail, but the
best thing to do is looking at the code (the filenames in Zend/ give a
good idea what they are for ...), take a question and time and start
digging. For some things it's also good to look into xdebug, vld,
runkit, ... and see where they hook in to do their magic. And well, the
path from main() in sapi/cli/php_cli.c to execute() is not that long,
what then happens is a bit more complicated though (while then again,
once you're in, quite easy for most parts, too)

johannes

---

## #61068 — Christopher Jones — 2012-07-02T18:05:27+00:00

URL: https://externals.io/message/60743#61068 · In reply to: #61060

> 

> > […]
>
> Use the source. ;-)
>
> A bit more seriously: No, there's no good single place to look at, there
> are different blogs etc looking at specific pieces in detail, but the
> best thing to do is looking at the code (the filenames in Zend/ give a
> good idea what they are for ...), take a question and time and start
> digging. For some things it's also good to look into xdebug, vld,
> runkit, ... and see where they hook in to do their magic. And well, the
> path from main() in sapi/cli/php_cli.c to execute() is not that long,
> what then happens is a bit more complicated though (while then again,
> once you're in, quite easy for most parts, too)
>
> johannes

There is a wiki page linking to some useful resources: https://wiki.php.net/internals/references

Chris

-- 
christopher.jones@oracle.com
http://twitter.com/#!/ghrd
