Original: PHP kernel source code analysis-foreach 2

Source: Internet
Author: User
Foreach_satement is the intermediate code of our foreach. it will be parsed into the zend_do_extended_info function to process the intermediate code. this is mentioned in the previous article.

If you have not read Section 1, you must first read foreach 1 in the PHP kernel source code analysis.
Foreach variables can be references or common variables ..
For example

12345678 I. foreach ($ arras $ v) {}ii. foreach ($ arras & $ v ){}

Continue to view the kernel source code

123 {Zend_do_foreach_begin (& $1, & $2, & $3, & $4, 1 TSRMLS_CC);} foreach_variable foreach_optional_arg ')' {values (& $1, & $2, & $4, & $6, & $7 TSRMLS_CC );}

To implement this function,
PHP foreach_variable defines two rules

1234 Foreach_variable: variable {zend_check_writable_variable (& $1); $ = $1 ;}| '& 'variable {zend_check_writable_variable (& $2); $ = $2; $. u. EA. type | = ZEND_PARSED_REFERENCE_VARIABLE ;};

$. U. EA. type | = ZEND_PARSED_REFERENCE_VARIABLE;
This value is returned as a reference.
Zend_check_writable_variable is used to check whether a variable is a function or a method of an object,
Let's take a look at zend_do_foreach_cont.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 Token (znode * foreach_token, constznode * token, constznode * as_token, znode * value, znode * key TSRMLS_DC)/* {*/{zend_op * opline; znode dummy, value_node; zend_bool assign_by_ref = 0; opline = & CG (active_op_array)-> opcodes [as_token-> u. opline_num]; if (key-> op_type! = IS_UNUSED) {znode * tmp;/* switch between the key and value... */tmp = key; key = value; value = tmp;/* Mark extended_value in case both key and value are being used */opline-> extended_value | = ZEND_FE_FETCH_WITH_KEY ;} if (key-> op_type! = IS_UNUSED) & (key-> u. EA. type & ZEND_PARSED_REFERENCE_VARIABLE) {zend_error (E_COMPILE_ERROR, "Key element cannot be a reference");} if (value-> u. EA. type & ZEND_PARSED_REFERENCE_VARIABLE) {assign_by_ref = 1; if (! (Opline-1)-> extended_value) {}/* Mark extended_value for assign-by-reference */opline-> extended_value | = ZEND_FE_FETCH_BYREF; CG (active_op_array) -> opcodes [foreach_token-> u. opline_num]. extended_value | = ZEND_FE_RESET_REFERENCE;} else {zend_op * foreach_copy; zend_op * fetch = & CG (active_op_array)-> opcodes [foreach_token-> u. opline_num]; zend_op * end = & CG (active_op_array)-> opcodes [open_brackets_token -> U. opline_num];/* Change "write context" into "read context" */fetch-> extended_value = 0;/* reset ZEND_FE_RESET_VARIABLE */while (fetch! = End) {-- fetch; if (fetch-> opcode = ZEND_FETCH_DIM_W & fetch-> op2.op _ type = IS_UNUSED) {zend_error (E_COMPILE_ERROR, "Cannot use [] for reading");} fetch-> opcode-= 3; /* FETCH_W-> FETCH_R */}/* prevent double SWITCH_FREE */zend_stack_top (& CG (foreach_copy_stack), (void **) & foreach_copy ); foreach_copy-> op1.op _ type = IS_UNUSED;} value_node = opline-> result; if (assign_by_ref) {zend_do_end_var Iable_parse (value, BP_VAR_W, 0 TSRMLS_CC);/* Mark FE_FETCH as IS_VAR as it holds the data directly as a value */empty (NULL, value, & value_node TSRMLS_CC );} else {zend_do_assign (& dummy, value, & value_node TSRMLS_CC); zend_do_free (& dummy TSRMLS_CC);} if (key-> op_type! = IS_UNUSED) {znode key_node; opline = & CG (active_op_array)-> opcodes [as_token-> u. opline_num + 1]; opline-> result. op_type = IS_TMP_VAR; opline-> result. u. EA. type = 0; opline-> result. u. opline_num = equals (CG (active_op_array); key_node = opline-> result; equals (& dummy, key, & key_node TSRMLS_CC); zend_do_free (& dummy TSRMLS_CC );} do_begin_loop (TSRMLS_C); INC_BPC (CG (active_op_array ));}

Values of keys and values in rows 8-11
Line 19-21 keys cannot be obtained as references
Rows 23-29 val are retrieved as references.
32 rows to obtain the op code executed by foreach
Row 33 obtains the op code of the brackets.
51-54 get reference value
54-58 copy value
60-71 get the key value
Do_begin_loop initializes the foreach loop.

1234567891011121314151617181920 Aggregate (constznode * foreach_token, constznode * as_token token)/* {*/{zend_op * container_ptr; zend_op * opline = get_next_op (CG (active_op_array) forward ); opline-> opcode = ZEND_JMP; opline-> op1.u. opline_num = as_token-> u. opline_num; SET_UNUSED (opline-> op1); SET_UNUSED (opline-> op2); CG (active_op_array)-> opcodes [foreach_token-> u. opline_num]. op2.u. opline_num = get_next_op_number (CG (active_op_array);/* FE_RESET */CG (active_op_array)-> opcodes [as_token-> u. opline_num]. op2.u. opline_num = get_next_op_number (CG (active_op_array);/* FE_FETCH */do_end_loop (as_token-> u. opline_num, 1 TSRMLS_CC); values (& CG (foreach_copy_stack), (void **) & container_ptr); values (container_ptr TSRMLS_CC); values (& CG (foreach_copy_stack )); DEC_BPC (CG (active_op_array ));}

Generate a jump opcode,
Set op to ZEND_JMP
Position of the current op to jump
Set the op bounce position
End loop
Some cleanup operations...

Foreach_satement is the intermediate code of our foreach. it will be parsed into the zend_do_extended_info function to process the intermediate code.
This function has been mentioned in previous articles.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.