1 // BEGIN INCLUDED FILES
2 /* The difference between zend_symtable_X and zend_hash_X is that
3 * the _symtable version will check if the key is a string of an
4 * integer, and if so, use the int version instead. We can use the
5 * zend_hash_X versions safely for symbol tables, since
6 * variables cant be integer strings, but we cant safely use
7 * zend_hash_X versions for hashtable lookups. Well-named, they are.
10 /* An important note of zval*s and zval**s. Frequently, zval** are
11 * fetched from arrays and symbol tables. The zval** will point into
12 * the array, and so updating it will update the relevant array
13 * entry. It is normally not the same to dereference it to a local
14 * variable, and pass a reference to that.
19 // Some common functions
23 * The runtime needs its own initialization and finalization. phc is
24 * responsible for generating calls to these functions.
38 ht_debug (HashTable
* ht
)
46 for (zend_hash_internal_pointer_reset (ht
);
47 zend_hash_has_more_elements (ht
) == SUCCESS
;
48 zend_hash_move_forward (ht
))
57 type
= zend_hash_get_current_key_ex (ht
, &key
, &keylen
, &idx
, 0, NULL
);
58 zend_hash_get_current_data (ht
, (void **) &ppzval
);
62 if (type
== HASH_KEY_IS_STRING
)
71 printf (": addr = %08lX, refcount = %d, is_ref = %d ",
72 (long unsigned int) (*ppzval
), (*ppzval
)->refcount
,
74 switch (Z_TYPE_P (zvp
))
80 printf ("(%ldL)", Z_LVAL_P (zvp
));
83 printf ("(%lff)", Z_DVAL_P (zvp
));
86 printf (Z_BVAL_P (zvp
) ? "(true)" : "(false)");
89 printf ("(array(%d))", Z_ARRVAL_P (zvp
)->nNumOfElements
);
95 printf ("(\"%s\")", Z_STRVAL_P (zvp
));
98 printf ("(Resource)");
101 printf ("(Invalid: %d)", Z_TYPE_P (zvp
));
107 printf ("END HASH\n");
110 // Call ht_debug on the named var in the given symbol table
112 ht_var_debug (HashTable
* st
, char *name
)
115 if (zend_symtable_find (st
, name
, strlen (name
) + 1,
116 (void **) &p_zvp
) != SUCCESS
)
118 printf ("VAR NOT IN SYMBOL TABLE: '%s'\n", name
);
122 if (Z_TYPE_P (*p_zvp
) != IS_ARRAY
)
124 printf ("NOT HASH\n");
128 ht_debug ((*p_zvp
)->value
.ht
);
131 static zval
* counters
;
133 static void init_counters ()
135 ALLOC_INIT_ZVAL (counters
);
136 array_init (counters
);
139 // Dump and cleanup memory
140 static void finalize_counters ()
142 HashTable
* ht
= Z_ARRVAL_P (counters
);
143 for (zend_hash_internal_pointer_reset (ht
);
144 zend_hash_has_more_elements (ht
) == SUCCESS
;
145 zend_hash_move_forward (ht
))
150 zend_hash_get_current_key_ex (ht
, &key
, NULL
, NULL
, 0, NULL
);
151 zend_hash_get_current_data (ht
, (void **) &p_zvp
);
153 fprintf (stderr
, "COUNTER:%s:%ld\n", key
, Z_LVAL_P (*p_zvp
));
156 zval_ptr_dtor (&counters
);
159 static void increment_counter (char* name
, int length
, ulong hashval
)
162 int success
= zend_hash_quick_find (Z_ARRVAL_P (counters
),
168 if (success
== SUCCESS
)
176 ALLOC_INIT_ZVAL (new_val
);
177 ZVAL_LONG (new_val
, 1);
179 zend_hash_quick_add (Z_ARRVAL_P (counters
),
191 /* Make a copy of *P_ZVP, storing it in *P_ZVP. */
193 zvp_clone_ex (zval
* zvp
)
195 // TODO: use INIT_PZVAL_COPY
197 MAKE_STD_ZVAL (clone
);
198 clone
->value
= zvp
->value
;
199 clone
->type
= zvp
->type
;
200 zval_copy_ctor (clone
);
206 in_copy_on_write (zval
* zvp
)
208 return (zvp
->refcount
> 1 && !zvp
->is_ref
);
212 in_change_on_write (zval
* zvp
)
214 return (zvp
->refcount
> 1 && zvp
->is_ref
);
217 /* If *P_ZVP is in a copy-on-write set, separate it by overwriting
218 * *P_ZVP with a clone of itself, and lowering the refcount on the
221 sep_copy_on_write (zval
** p_zvp
)
223 if (!in_copy_on_write (*p_zvp
))
228 *p_zvp
= zvp_clone_ex (*p_zvp
);
230 zval_ptr_dtor (&old
);
233 /* If *P_ZVP is in a copy-on-write set, separate it by overwriting
234 * *P_ZVP with a clone of itself, and lowering the refcount on the
237 sep_change_on_write (zval
** p_zvp
)
239 assert (in_change_on_write (*p_zvp
));
243 *p_zvp
= zvp_clone_ex (*p_zvp
);
245 zval_ptr_dtor (&old
);
248 /* Assign RHS into LHS, by reference. After this, LHS will point to the same
251 copy_into_ref (zval
** lhs
, zval
** rhs
)
260 // Overwrite one zval with another
262 overwrite_lhs (zval
* lhs
, zval
* rhs
)
264 // First, call the destructor to remove any data structures
265 // associated with lhs that will now be overwritten
268 lhs
->value
= rhs
->value
;
269 lhs
->type
= rhs
->type
;
270 zval_copy_ctor (lhs
);
273 // Overwrite one zval with another
275 overwrite_lhs_no_copy (zval
* lhs
, zval
* rhs
)
277 // First, call the destructor to remove any data structures
278 // associated with lhs that will now be overwritten
281 lhs
->value
= rhs
->value
;
282 lhs
->type
= rhs
->type
;
285 /* Write P_RHS into the symbol table as a variable named VAR_NAME. */
286 // NOTE: We do not alter p_rhs's refcount, unless p_lhs joins its
287 // Copy-on-write set.
288 // TODO: this is crying out to be inlined.
290 write_var (zval
** p_lhs
, zval
* rhs
)
292 if (!(*p_lhs
)->is_ref
)
294 zval_ptr_dtor (p_lhs
);
295 // Take a copy of RHS for LHS.
298 *p_lhs
= zvp_clone_ex (rhs
);
308 overwrite_lhs (*p_lhs
, rhs
);
312 // TODO: this functino does too much, and much might be redundant
314 get_st_entry (HashTable
* st
, char *name
, int length
, ulong hashval TSRMLS_DC
)
317 if (zend_hash_quick_find
318 (st
, name
, length
, hashval
, (void **) &p_zvp
) == SUCCESS
)
320 assert (p_zvp
!= NULL
);
324 // If we dont find it, put EG (uninitialized_zval_ptr) into the
325 // hashtable, and return a pointer to its container.
326 EG (uninitialized_zval_ptr
)->refcount
++;
327 int result
= zend_hash_quick_add (st
, name
, length
, hashval
,
328 &EG (uninitialized_zval_ptr
),
329 sizeof (zval
*), (void **) &p_zvp
);
330 assert (result
== SUCCESS
);
331 assert (p_zvp
!= NULL
);
336 /* Read the variable named VAR_NAME from the local symbol table and
337 * return it. If the variable doent exist, a new one is created and
340 read_var (HashTable
* st
, char *name
, int length
, ulong hashval TSRMLS_DC
)
343 if (zend_hash_quick_find
344 (st
, name
, length
, hashval
, (void **) &p_zvp
) == SUCCESS
)
347 return EG (uninitialized_zval_ptr
);
351 get_integer_index (zval
* ind TSRMLS_DC
)
354 switch (Z_TYPE_P (ind
))
357 return (long) Z_DVAL_P (ind
);
361 return Z_LVAL_P (ind
);
367 php_error_docref (NULL TSRMLS_CC
, E_WARNING
, "Illegal offset type");
372 read_string_index (zval
* var
, zval
* ind TSRMLS_DC
)
374 // This must always allocate memory, since we cant return the
376 assert (Z_TYPE_P (var
) == IS_STRING
);
377 long index
= get_integer_index (ind TSRMLS_CC
);
380 ALLOC_INIT_ZVAL (result
);
382 if (index
>= Z_STRLEN_P (var
) || index
< 0)
384 // this is 1 byte long, must be copied
385 ZVAL_STRINGL (result
, "", 0, 1);
389 char *string
= Z_STRVAL_P (var
);
390 ZVAL_STRINGL (result
, &string
[index
], 1, 1);
396 /* Given a string (p_lhs), write into it for $x[i] = $y; */
398 write_string_index (zval
** p_lhs
, zval
* ind
, zval
* rhs TSRMLS_DC
)
400 assert (Z_TYPE_P (*p_lhs
) == IS_STRING
);
402 long index
= get_integer_index (ind TSRMLS_CC
);
404 // Get the appropriate character
406 if (Z_TYPE_P (rhs
) != IS_STRING
)
408 // TODO: remove allocate
409 zval
*copy
= zvp_clone_ex (rhs
);
410 convert_to_string (copy
);
411 new_char
= Z_STRVAL_P (copy
)[0];
412 zval_ptr_dtor (©
);
416 new_char
= Z_STRVAL_P (rhs
)[0];
422 php_error_docref (NULL TSRMLS_CC
, E_WARNING
,
423 "Illegal string offset: %ld", index
);
427 // We overwrite if it's change-on-write
428 sep_copy_on_write (p_lhs
);
430 if (index
> Z_STRLEN_PP (p_lhs
))
433 int len
= Z_STRLEN_PP (p_lhs
);
434 int new_length
= index
+ 1; // space for the new character
435 Z_STRVAL_PP (p_lhs
) = erealloc (Z_STRVAL_PP (p_lhs
), new_length
+ 1);
438 memset (&Z_STRVAL_PP (p_lhs
)[len
], ' ', index
- len
);
441 Z_STRLEN_PP (p_lhs
) = new_length
;
443 // add a null terminator
444 Z_STRVAL_PP (p_lhs
)[new_length
] = '\0';
447 // write in the first character of the new value
448 Z_STRVAL_PP (p_lhs
)[index
] = new_char
;
451 // index < 0: E_WARNING illegal string offset
454 // Extract the hashtable from a hash-valued zval
456 extract_ht_ex (zval
* arr TSRMLS_DC
)
458 // TODO: this likely should be inlined somewhere.
459 assert (!in_copy_on_write (arr
));
460 if (Z_TYPE_P (arr
) == IS_NULL
)
464 else if (Z_TYPE_P (arr
) != IS_ARRAY
)
466 php_error_docref (NULL TSRMLS_CC
, E_WARNING
,
467 "Cannot use a scalar value as an array");
470 return Z_ARRVAL_P (arr
);
474 /* P_VAR points into a symbol table, at a variable which we wish to index as a hashtable. */
476 extract_ht (zval
** p_var TSRMLS_DC
)
478 sep_copy_on_write (p_var
);
480 return extract_ht_ex (*p_var TSRMLS_CC
);
483 /* Using IND as a key to HT, call the appropriate zend_index_X
484 * function with data as a parameter, and return its result. This
485 * updates the zval** pointed to by DATA. */
487 ht_find (HashTable
* ht
, zval
* ind
, zval
*** data
)
490 if (Z_TYPE_P (ind
) == IS_LONG
|| Z_TYPE_P (ind
) == IS_BOOL
)
492 result
= zend_hash_index_find (ht
, Z_LVAL_P (ind
), (void **) data
);
494 else if (Z_TYPE_P (ind
) == IS_DOUBLE
)
496 result
= zend_hash_index_find (ht
, (long) Z_DVAL_P (ind
),
499 else if (Z_TYPE_P (ind
) == IS_NULL
)
501 result
= zend_hash_find (ht
, "", sizeof (""), (void **)data
);
503 else if (Z_TYPE_P (ind
) == IS_STRING
)
505 result
= zend_symtable_find (ht
, Z_STRVAL_P (ind
),
506 Z_STRLEN_P (ind
) + 1, (void **) data
);
510 // TODO: I believe this might need a warning.
513 // use a string index for other types
515 MAKE_STD_ZVAL (string_index
);
516 string_index
->value
= ind
->value
;
517 string_index
->type
= ind
->type
;
518 zval_copy_ctor (string_index
);
519 convert_to_string (string_index
);
521 result
= zend_symtable_find (ht
, Z_STRVAL_P (string_index
),
522 Z_STRLEN_P (string_index
) + 1,
524 zval_ptr_dtor (&string_index
);
531 check_array_index_type (zval
* ind TSRMLS_DC
)
533 if (Z_TYPE_P (ind
) == IS_OBJECT
|| Z_TYPE_P (ind
) == IS_ARRAY
)
535 php_error_docref (NULL TSRMLS_CC
, E_WARNING
, "Illegal offset type");
542 // Update a hashtable using a zval* index
544 ht_update (HashTable
* ht
, zval
* ind
, zval
* val
, zval
*** dest
)
547 if (Z_TYPE_P (ind
) == IS_LONG
|| Z_TYPE_P (ind
) == IS_BOOL
)
549 result
= zend_hash_index_update (ht
, Z_LVAL_P (ind
), &val
,
550 sizeof (zval
*), (void **) dest
);
552 else if (Z_TYPE_P (ind
) == IS_DOUBLE
)
554 result
= zend_hash_index_update (ht
, (long) Z_DVAL_P (ind
),
555 &val
, sizeof (zval
*), (void **) dest
);
557 else if (Z_TYPE_P (ind
) == IS_NULL
)
559 result
= zend_hash_update (ht
, "", sizeof (""), &val
,
560 sizeof (zval
*), (void **) dest
);
562 else if (Z_TYPE_P (ind
) == IS_STRING
)
564 result
= zend_symtable_update (ht
, Z_STRVAL_P (ind
),
565 Z_STRLEN_P (ind
) + 1,
566 &val
, sizeof (zval
*), (void **) dest
);
572 MAKE_STD_ZVAL (string_index
);
573 string_index
->value
= ind
->value
;
574 string_index
->type
= ind
->type
;
575 zval_copy_ctor (string_index
);
576 convert_to_string (string_index
);
577 result
= zend_symtable_update (ht
, Z_STRVAL_P (string_index
),
578 Z_STRLEN_P (string_index
) + 1,
579 &val
, sizeof (zval
*), (void **) dest
);
581 zval_ptr_dtor (&string_index
);
583 assert (result
== SUCCESS
);
586 // Delete from a hashtable using a zval* index
588 ht_delete (HashTable
* ht
, zval
* ind
)
590 // This may fail if the index doesnt exist, which is fine.
591 if (Z_TYPE_P (ind
) == IS_LONG
|| Z_TYPE_P (ind
) == IS_BOOL
)
593 zend_hash_index_del (ht
, Z_LVAL_P (ind
));
595 else if (Z_TYPE_P (ind
) == IS_DOUBLE
)
597 zend_hash_index_del (ht
, (long) Z_DVAL_P (ind
));
599 else if (Z_TYPE_P (ind
) == IS_NULL
)
601 zend_hash_del (ht
, "", sizeof (""));
603 else if (Z_TYPE_P (ind
) == IS_STRING
)
605 zend_hash_del (ht
, Z_STRVAL_P (ind
), Z_STRLEN_P (ind
) + 1);
611 MAKE_STD_ZVAL (string_index
);
612 string_index
->value
= ind
->value
;
613 string_index
->type
= ind
->type
;
614 zval_copy_ctor (string_index
);
615 convert_to_string (string_index
);
616 zend_hash_del (ht
, Z_STRVAL_P (string_index
),
617 Z_STRLEN_P (string_index
) + 1);
619 zval_ptr_dtor (&string_index
);
623 // Check if a key exists in a hashtable
625 ht_exists (HashTable
* ht
, zval
* ind
)
627 if (Z_TYPE_P (ind
) == IS_LONG
|| Z_TYPE_P (ind
) == IS_BOOL
)
629 return zend_hash_index_exists (ht
, Z_LVAL_P (ind
));
631 else if (Z_TYPE_P (ind
) == IS_DOUBLE
)
633 return zend_hash_index_exists (ht
, (long) Z_DVAL_P (ind
));
635 else if (Z_TYPE_P (ind
) == IS_NULL
)
637 return zend_hash_exists (ht
, "", sizeof (""));
639 else if (Z_TYPE_P (ind
) == IS_STRING
)
641 return zend_hash_exists (ht
, Z_STRVAL_P (ind
), Z_STRLEN_P (ind
) + 1);
648 MAKE_STD_ZVAL (string_index
);
649 string_index
->value
= ind
->value
;
650 string_index
->type
= ind
->type
;
651 zval_copy_ctor (string_index
);
652 convert_to_string (string_index
);
653 result
= zend_hash_exists (ht
, Z_STRVAL_P (string_index
),
654 Z_STRLEN_P (string_index
) + 1);
655 zval_ptr_dtor (&string_index
);
662 get_ht_entry (zval
** p_var
, zval
* ind TSRMLS_DC
)
664 if (Z_TYPE_P (*p_var
) == IS_STRING
)
666 if (Z_STRLEN_PP (p_var
) > 0)
668 php_error_docref (NULL TSRMLS_CC
, E_ERROR
,
669 "Cannot create references to/from string offsets nor overloaded objects");
673 if (Z_TYPE_P (*p_var
) != IS_ARRAY
)
675 zval_ptr_dtor (p_var
);
676 ALLOC_INIT_ZVAL (*p_var
);
680 HashTable
*ht
= extract_ht (p_var TSRMLS_CC
);
683 if (ht_find (ht
, ind
, &data
) == SUCCESS
)
685 assert (data
!= NULL
);
689 // If we dont find it, put EG (uninitialized_zval_ptr) into the
690 // hashtable, and return a pointer to its container.
691 EG (uninitialized_zval_ptr
)->refcount
++;
692 ht_update (ht
, ind
, EG (uninitialized_zval_ptr
), &data
);
694 assert (data
!= NULL
);
700 // Like extract_ht_ex, but for objects
702 extract_field_ex (zval
* obj TSRMLS_DC
)
704 // TODO: this likely should be inlined somewhere.
705 assert (!in_copy_on_write (obj
));
706 if (Z_TYPE_P (obj
) == IS_NULL
)
709 // TODO: implement initialization
711 else if (Z_TYPE_P (obj
) != IS_OBJECT
)
713 // TODO: test if this is the right error message
714 php_error_docref (NULL TSRMLS_CC
, E_WARNING
,
715 "Cannot use a scalar value as an object");
716 // TODO: implement initialization
719 return Z_OBJPROP_P (obj
);
722 // Like extract_ht, but for objects
724 extract_field (zval
** p_var TSRMLS_DC
)
726 sep_copy_on_write (p_var
);
728 return extract_field_ex (*p_var TSRMLS_CC
);
731 // Like get_ht_entry, but for objects
733 get_field (zval
** p_var
, char *ind TSRMLS_DC
)
735 if (Z_TYPE_P (*p_var
) != IS_OBJECT
)
737 // TODO: implement initialization
741 HashTable
*ht
= extract_field (p_var TSRMLS_CC
);
744 if (zend_symtable_find (ht
, ind
, strlen (ind
) + 1, (void **) &data
) ==
747 assert (data
!= NULL
);
751 // If we dont find it, put EG (uninitialized_zval_ptr) into the
752 // hashtable, and return a pointer to its container.
753 EG (uninitialized_zval_ptr
)->refcount
++;
754 zend_symtable_update (ht
, ind
, strlen (ind
) + 1,
755 &EG (uninitialized_zval_ptr
), sizeof (zval
*),
758 assert (data
!= NULL
);
764 read_array (zval
** result
, zval
* array
, zval
* ind TSRMLS_DC
)
766 // Memory can be allocated in read_string_index
767 if (array
== EG (uninitialized_zval_ptr
))
773 // Since we know its an array, and we dont write to it, we dont need
775 HashTable
*ht
= Z_ARRVAL_P (array
);
779 if (ht_find (ht
, ind
, &p_result
) == SUCCESS
)
785 *result
= EG (uninitialized_zval_ptr
);
788 /* If its not an array, convert it into an array. */
790 check_array_type (zval
** p_var TSRMLS_DC
)
792 if ((Z_TYPE_P (*p_var
) == IS_BOOL
&& !Z_BVAL_PP (p_var
))
793 || Z_TYPE_P (*p_var
) == IS_NULL
794 || (Z_TYPE_P (*p_var
) == IS_STRING
&& Z_STRLEN_PP (p_var
) == 0))
796 // Non ref use new values
797 if (!PZVAL_IS_REF (*p_var
))
799 zval_ptr_dtor (p_var
);
800 ALLOC_INIT_ZVAL (*p_var
);
803 // Refs are just replaced
808 else if (Z_TYPE_PP (p_var
) != IS_STRING
&& Z_TYPE_PP (p_var
) != IS_ARRAY
)
810 // TODO: why are these different types than pushing
811 php_error_docref (NULL TSRMLS_CC
, E_WARNING
,
812 "Cannot use a scalar value as an array");
816 /* If its not an array, convert it into an object. */
818 check_object_type (zval
** p_var TSRMLS_DC
)
823 /* Push EG (uninitialized_zval_ptr) and return a pointer into the ht
826 * Converted to array automatically:
831 * Warning, no conversion:
836 * Error, no conversion:
837 * strings other than ""
839 // TODO: objects, resources, etc
841 push_and_index_ht (zval
** p_var TSRMLS_DC
)
843 // Check for errors conditions
845 if (Z_TYPE_P (*p_var
) == IS_STRING
&& Z_STRLEN_PP (p_var
) > 0)
847 php_error_docref (NULL TSRMLS_CC
, E_ERROR
,
848 "[] operator not supported for strings");
849 assert (0); // unreachable
852 if (Z_TYPE_P (*p_var
) == IS_BOOL
&& Z_BVAL_PP (p_var
)
853 || Z_TYPE_P (*p_var
) == IS_LONG
|| Z_TYPE_P (*p_var
) == IS_DOUBLE
)
855 php_error_docref (NULL TSRMLS_CC
, E_WARNING
,
856 "Cannot use a scalar value as an array");
860 if (Z_TYPE_P (*p_var
) != IS_ARRAY
)
862 zval_ptr_dtor (p_var
);
863 ALLOC_INIT_ZVAL (*p_var
);
867 // if its not an array, make it an array
868 HashTable
*ht
= extract_ht (p_var TSRMLS_CC
);
871 EG (uninitialized_zval_ptr
)->refcount
++;
872 int result
= zend_hash_next_index_insert (ht
, &EG (uninitialized_zval_ptr
),
873 sizeof (zval
*), (void **) &data
);
874 assert (result
== SUCCESS
);
886 isset_var (HashTable
* st
, char *name
, int length
)
888 return zend_hash_exists (st
, name
, length
);
892 isset_array (zval
** p_var
, zval
* ind
)
894 if (Z_TYPE_P (*p_var
) == IS_STRING
)
896 ind
= zvp_clone_ex (ind
);
897 convert_to_long (ind
);
898 int result
= (Z_LVAL_P (ind
) >= 0
899 && Z_LVAL_P (ind
) < Z_STRLEN_PP (p_var
));
900 assert (ind
->refcount
== 1);
901 zval_ptr_dtor (&ind
);
905 // NO error required; return false
906 if (Z_TYPE_P (*p_var
) != IS_ARRAY
)
909 // if its not an array, make it an array
910 HashTable
*ht
= Z_ARRVAL_P (*p_var
);
913 if (ht_find (ht
, ind
, &data
) == SUCCESS
)
915 return !ZVAL_IS_NULL (*data
);
923 fetch_var_arg_by_ref (zval
** p_arg
)
925 // We are passing by reference
926 sep_copy_on_write (p_arg
);
928 // We don't need to restore ->is_ref afterwards,
929 // because the called function will reduce the
930 // refcount of arg on return, and will reset is_ref to
931 // 0 when refcount drops to 1. If the refcount does
932 // not drop to 1 when the function returns, but we did
933 // set is_ref to 1 here, that means that is_ref must
934 // already have been 1 to start with (since if it had
935 // not, that means that the variable would have been
936 // in a copy-on-write set, and would have been
938 (*p_arg
)->is_ref
= 1;
943 /* Dont pass-by-ref */
945 fetch_var_arg (zval
* arg
, int *is_arg_new
)
949 // We dont separate since we don't own one of ARG's references.
950 arg
= zvp_clone_ex (arg
);
953 // It seems we get incorrect refcounts without this.
954 // TODO This decreases the refcount to zero, which seems wrong,
955 // but gives the right answer. We should look at how zend does
963 // TODO dont overwrite line numbers if we're compiling an extension
965 phc_setup_error (int init
, char *filename
, int line_number
,
966 zend_function
* function TSRMLS_DC
)
968 static int old_in_compilation
;
969 static int old_in_execution
;
970 static char *old_filename
;
971 static int old_lineno
;
972 static zend_function
*old_function
;
975 if (filename
== NULL
)
976 filename
= "[phc_compiled_file]";
978 old_in_compilation
= CG (in_compilation
);
979 old_in_execution
= EG (in_execution
);
980 old_filename
= CG (compiled_filename
);
981 old_lineno
= CG (zend_lineno
);
982 old_function
= EG (function_state_ptr
)->function
;
984 CG (in_compilation
) = 1;
985 EG (in_execution
) = 1;
986 CG (compiled_filename
) = filename
;
987 CG (zend_lineno
) = line_number
;
989 EG (function_state_ptr
)->function
= function
;
993 CG (in_compilation
) = old_in_compilation
;
994 EG (in_execution
) = old_in_execution
;
995 CG (compiled_filename
) = old_filename
;
996 CG (zend_lineno
) = old_lineno
;
997 EG (function_state_ptr
)->function
= old_function
;
1002 initialize_function_call (zend_fcall_info
* fci
, zend_fcall_info_cache
* fcic
,
1003 char *function_name
, char *filename
,
1004 int line_number TSRMLS_DC
)
1006 if (fcic
->initialized
)
1011 ZVAL_STRING (&fn
, function_name
, 0);
1012 int result
= zend_fcall_info_init (&fn
, fci
, fcic TSRMLS_CC
);
1013 if (result
!= SUCCESS
)
1015 phc_setup_error (1, filename
, line_number
, NULL TSRMLS_CC
);
1016 php_error_docref (NULL TSRMLS_CC
, E_ERROR
,
1017 "Call to undefined function %s()", function_name
);
1022 * Initialize zend_fcall_info for a method lookup
1024 * Implementation partly based on zend_call_method in Zend/zend_interfaces.c
1025 * Main difference is that we use Z_OBJ_HTT_PP(obj)->get_method to retrieve
1026 * the function handler for the method instead of looking it up directly;
1027 * this means that we correctly deal with __call.
1031 initialize_method_call (zend_fcall_info
* fci
, zend_fcall_info_cache
* fcic
,
1032 zval
** obj
, char *function_name
,
1033 char *filename
, int line_number TSRMLS_DC
)
1035 if (fcic
->initialized
)
1038 zend_class_entry
*obj_ce
;
1039 obj_ce
= Z_OBJCE_PP (obj
);
1042 * we do not initialize fci.
1043 * function_table -- not initialized by zend_call_method
1044 * function_name -- zend_call_method initializes this to a pointer to
1045 * a zval 'z_fname', but does not initialize z_fname
1046 * in case of a method invocation
1047 * retval_ptr_ptr -- should be initialized by caller
1048 * param_count -- should be initialized by caller
1049 * params -- should be initialized by caller
1051 fci
->size
= sizeof (*fci
);
1052 fci
->object_pp
= obj
;
1053 fci
->no_separation
= 1;
1054 fci
->symbol_table
= NULL
;
1056 fcic
->initialized
= 1;
1057 fcic
->calling_scope
= obj_ce
;
1058 fcic
->object_pp
= obj
;
1059 fcic
->function_handler
1060 = Z_OBJ_HT_PP (obj
)->get_method (obj
,
1062 strlen (function_name
) TSRMLS_CC
);
1064 if (fcic
->function_handler
== NULL
)
1066 phc_setup_error (1, filename
, line_number
, NULL TSRMLS_CC
);
1067 php_error_docref (NULL TSRMLS_CC
, E_ERROR
,
1068 "Call to undefined method %s::%s",
1069 obj_ce
->name
, function_name
);
1074 * Like initialize_method_call, but return 0 if no constructor is defined
1075 * rather than giving an error.
1079 initialize_constructor_call (zend_fcall_info
* fci
,
1080 zend_fcall_info_cache
* fcic
, zval
** obj
,
1081 char *filename
, int line_number TSRMLS_DC
)
1083 if (fcic
->initialized
)
1086 zend_class_entry
*obj_ce
;
1087 obj_ce
= Z_OBJCE_PP (obj
);
1090 * we do not initialize fci.
1091 * function_table -- not initialized by zend_call_method
1092 * function_name -- zend_call_method initializes this to a pointer to
1093 * a zval 'z_fname', but does not initialize z_fname
1094 * in case of a method invocation
1095 * retval_ptr_ptr -- should be initialized by caller
1096 * param_count -- should be initialized by caller
1097 * params -- should be initialized by caller
1099 fci
->size
= sizeof (*fci
);
1100 fci
->object_pp
= obj
;
1101 fci
->no_separation
= 1;
1102 fci
->symbol_table
= NULL
;
1104 fcic
->initialized
= 1;
1105 fcic
->calling_scope
= obj_ce
;
1106 fcic
->object_pp
= obj
;
1107 fcic
->function_handler
1108 = Z_OBJ_HT_PP (obj
)->get_constructor (*obj TSRMLS_CC
);
1110 return (fcic
->function_handler
!= NULL
);
1115 * Creates a copy of *in using persistent memory, optionally destroying *in
1117 * Does not work for objects/resources and will loop on self-recursive arrays.
1121 persistent_clone (zval
* in
, int destroy_in TSRMLS_DC
)
1123 zval
*out
= pemalloc (sizeof (zval
), 1);
1126 switch (Z_TYPE_P (in
))
1132 /* nothing more to be done */
1135 Z_STRVAL_P (out
) = pemalloc (Z_STRLEN_P (in
) + 1, 1);
1136 memcpy (Z_STRVAL_P (out
), Z_STRVAL_P (in
), Z_STRLEN_P (in
) + 1);
1140 HashTable
*old_arr
= Z_ARRVAL_P (in
);
1141 HashTable
*new_arr
= pemalloc (sizeof (HashTable
), 1);
1142 zend_hash_init (new_arr
, old_arr
->nNumOfElements
, NULL
, ZVAL_PTR_DTOR
,
1143 /* persistent */ 1);
1145 for (zend_hash_internal_pointer_reset (old_arr
);
1146 zend_hash_has_more_elements (old_arr
) == SUCCESS
;
1147 zend_hash_move_forward (old_arr
))
1153 zval
**old_elem
, *new_elem
;
1156 zend_hash_get_current_key_ex (old_arr
, &key
, &keylen
, &idx
, 0,
1158 assert (zend_hash_get_current_data
1159 (old_arr
, (void **) &old_elem
) == SUCCESS
);
1161 new_elem
= persistent_clone (*old_elem
, destroy_in TSRMLS_CC
);
1163 if (type
== HASH_KEY_IS_STRING
)
1164 zend_hash_add (new_arr
, key
, keylen
, &new_elem
, sizeof (zval
*),
1167 zend_hash_index_update (new_arr
, idx
, &new_elem
,
1168 sizeof (zval
*), NULL
);
1172 Z_ARRVAL_P (out
) = new_arr
;
1176 /* other types are not supported */
1180 zval_ptr_dtor (&in
);
1185 * Wrapper around zend_declare_property which
1187 * - Asserts that the ZEND_INTERNAL_CLASS flag is cleared
1188 * (otherwise we cannot add complex (i.e., array) properties)
1189 * - Creates a persistent clone of the property to be added before
1190 * calling zend_declare_property, since the memory for this property
1191 * should only be deallocated when the module is shut down
1192 * (and not when the request finishes)
1193 * - Cleans up after zend_declare_property by re-allocating the name of
1194 * the property using persistent memory, for much the same reason
1198 phc_declare_property (zend_class_entry
* ce
, char *name
, int name_length
,
1199 zval
* property
, int access_type TSRMLS_DC
)
1201 assert (!(ce
->type
& ZEND_INTERNAL_CLASS
));
1202 assert (zend_declare_property
1203 (ce
, name
, name_length
, persistent_clone (property
, 1 TSRMLS_CC
),
1204 access_type TSRMLS_CC
) == SUCCESS
);
1206 zend_property_info
*property_info
;
1207 assert (zend_hash_find
1208 (&ce
->properties_info
, name
, name_length
+ 1,
1209 (void **) &property_info
) == SUCCESS
);
1210 efree (property_info
->name
);
1211 property_info
->name
= name
;
1220 cast_var (zval
** p_zvp
, int type
)
1222 assert (type
>= 0 && type
<= 6);
1223 if ((*p_zvp
)->type
== type
)
1226 sep_copy_on_write (p_zvp
);
1232 convert_to_null (zvp
);
1235 convert_to_boolean (zvp
);
1238 convert_to_long (zvp
);
1241 convert_to_double (zvp
);
1244 convert_to_string (zvp
);
1247 convert_to_array (zvp
);
1250 convert_to_object (zvp
);
1253 assert (0); // TODO unimplemented
1258 /* Copies a constant into ZVP. Note that LENGTH does not include the NULL-terminating byte. */
1260 get_constant (char *name
, int length
, zval
** p_zvp TSRMLS_DC
)
1262 MAKE_STD_ZVAL (*p_zvp
);
1263 // zend_get_constant returns 1 for success, not SUCCESS
1264 int result
= zend_get_constant (name
, length
, *p_zvp TSRMLS_CC
);
1266 ZVAL_STRINGL (*p_zvp
, name
, length
, 1);
1269 /* The function call mechanism deals specially with EG(uninitialize_zval_ptr)
1270 * (or sometime EG(uninitialize_zval)), so we need to use this too. This
1271 * particular zval can also be set, but there is an implicit guarantee
1272 * of the information below.
1274 * If assertions are off, this should be inlined to nothing.
1277 phc_check_invariants (TSRMLS_D
)
1279 assert (EG (uninitialized_zval_ptr
) == &EG (uninitialized_zval
));
1280 assert (EG (uninitialized_zval
).refcount
>= 1);
1281 assert (EG (uninitialized_zval
).value
.lval
== 0);
1282 assert (EG (uninitialized_zval
).type
== IS_NULL
);
1283 assert (EG (uninitialized_zval
).is_ref
== 0);
1288 check_unset_index_type (zval
* ind TSRMLS_DC
)
1290 if (Z_TYPE_P (ind
) == IS_OBJECT
|| Z_TYPE_P (ind
) == IS_ARRAY
)
1292 php_error_docref (NULL TSRMLS_CC
, E_WARNING
,
1293 "Illegal offset type in unset");
1307 unset_var (HashTable
* st
, char *name
, int length
)
1309 zend_hash_del (st
, name
, length
);
1313 unset_array (zval
** p_var
, zval
* ind TSRMLS_DC
)
1315 // NO error required
1316 if (Z_TYPE_PP (p_var
) != IS_ARRAY
)
1318 if (Z_TYPE_PP (p_var
) == IS_STRING
)
1320 php_error_docref (NULL TSRMLS_CC
, E_ERROR
,
1321 "Cannot unset string offsets");
1323 else if (Z_TYPE_PP (p_var
) != IS_NULL
)
1325 php_error_docref (NULL TSRMLS_CC
, E_WARNING
,
1326 "Cannot unset offsets in a non-array variable");
1332 // if its not an array, make it an array
1333 HashTable
*ht
= Z_ARRVAL_P (*p_var
);
1335 ht_delete (ht
, ind
);
1339 * Lookup variable whose name is var_var in st. We do not call
1340 * ht_find because ht_find uses zend_symtable_find to search for strings
1341 * rather than zend_hash_find. The difference is that zend_symtable_find
1342 * will convert strings to integers where possible: arrays are always
1343 * integer-indexed if at all possible. Variable names however should
1344 * _always_ be treated as strings.
1349 * If the parameter is a string, returns the parameter, with the refcount
1350 * incremented. If its not a string, returns a new zval, with a refcount of
1351 * 1. Either way, zval_dtor_ptr must be run by the caller on the return
1355 get_string_val (zval
* zvp
)
1357 if (Z_TYPE_P (zvp
) == IS_STRING
)
1364 zval
* clone
= zvp_clone_ex (zvp
);
1365 convert_to_string (clone
);
1371 get_var_var (HashTable
* st
, zval
* index TSRMLS_DC
)
1373 zval
* str_index
= get_string_val (index
);
1374 char* name
= Z_STRVAL_P (str_index
);
1375 int length
= Z_STRLEN_P (str_index
) + 1;
1376 unsigned long hash
= zend_get_hash_value (name
, length
);
1378 zval
** result
= get_st_entry (st
, name
, length
, hash TSRMLS_CC
);
1379 zval_ptr_dtor (&str_index
);
1384 * Read the variable described by var_var from symbol table st
1385 * See comments for get_var_var
1388 read_var_var (HashTable
* st
, zval
* index TSRMLS_DC
)
1390 zval
* str_index
= get_string_val (index
);
1391 char* name
= Z_STRVAL_P (str_index
);
1392 int length
= Z_STRLEN_P (str_index
) + 1;
1393 unsigned long hash
= zend_get_hash_value (name
, length
);
1395 zval
* result
= read_var (st
, name
, length
, hash TSRMLS_CC
);
1396 zval_ptr_dtor (&str_index
);
1401 phc_builtin_eval (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1403 // If the user wrote "return ..", we need to store the
1404 // return value; however, in that case, zend_eval_string
1405 // will slap an extra "return" onto the front of the string,
1406 // so we must remove the "return" from the string the user
1407 // wrote. If the user did not write "return", he is not
1408 // interested in the return value, and we must pass NULL
1409 // instead or rhs to avoid zend_eval_string adding "return".
1411 // convert to a string
1412 // TODO avoid allocation
1413 zval
*copy
= zvp_clone_ex (arg
);
1414 convert_to_string (copy
);
1416 if (*p_result
&& !strncmp (Z_STRVAL_P (copy
), "return ", 7))
1418 zend_eval_string (Z_STRVAL_P (copy
) + 7, *p_result
,
1419 "eval'd code" TSRMLS_CC
);
1423 zend_eval_string (Z_STRVAL_P (copy
), NULL
, "eval'd code" TSRMLS_CC
);
1427 assert (copy
->refcount
== 1);
1428 zval_ptr_dtor (©
);
1432 phc_builtin_exit (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1434 if (Z_TYPE_P (arg
) == IS_LONG
)
1435 EG (exit_status
) = Z_LVAL_P (arg
);
1437 zend_print_variable (arg
);
1443 phc_builtin_die (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1445 phc_builtin_exit (arg
, p_result
, filename TSRMLS_CC
);
1449 phc_builtin_echo (zval
* arg
, zval
** p_result TSRMLS_DC
)
1451 assert (*p_result
== NULL
);
1452 zend_print_variable (arg
);
1456 phc_builtin_print (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1458 zval
*echo_arg
= NULL
;
1459 phc_builtin_echo (arg
, &echo_arg TSRMLS_CC
);
1462 ZVAL_LONG (*p_result
, 1);
1465 // TODO is there a memory leak here is result has a value?
1466 // TOOD isnt this just the same as isset
1468 phc_builtin_empty (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1471 ZVAL_BOOL (*p_result
, !zend_is_true (arg
));
1474 // For require, include, require_once and include_once.
1477 // return 1 for success
1478 // Warning, and return false for failure
1480 // return 1 for success
1483 // Return true if already included
1484 // Return 1 for success
1485 // Warning and return false for failure
1487 // Return true if already included
1488 // return 1 for success
1492 include_backend (zval
* arg
, zval
** p_result
, char *filename
, int type
, int is_once
, char* error
, char* error_function TSRMLS_DC
)
1494 // In the event that the Zend engine cannot find the file, after checking the
1495 // include path, it tries the current directory. It does this only if the
1496 // interpreter is executing, and it checks the interpreters opcodes for a
1497 // filename (see streams/plain_wrapper.c:1352)
1499 // An alternative is to add the directory to include_path, but its
1500 // semantically incorrect (get_included_path() would give the wrong answer),
1501 // and error prone (if people overwrite include_path).
1502 // TODO: though we could add it for this function only
1504 assert (EG (active_op_array
) == NULL
);
1505 assert (filename
!= NULL
);
1507 zval
*arg_file
= arg
;
1508 // Check we have a string
1509 if (Z_TYPE_P (arg_file
) != IS_STRING
)
1511 arg_file
= zvp_clone_ex (arg_file
);
1512 convert_to_string (arg_file
);
1515 zend_file_handle handle
;
1516 zend_op_array
* new_op_array
;
1519 // Check the _ONCE varieties (based on zend_vm_def.h)
1522 if (IS_ABSOLUTE_PATH (Z_STRVAL_P (arg_file
), Z_STRLEN_P (arg_file
)))
1524 // Get the proper path name for require
1527 state
.cwd_length
= 0;
1528 state
.cwd
= malloc(1);
1530 int success
= !virtual_file_ex(&state
, Z_STRVAL_P(arg_file
), NULL
, 1)
1531 && zend_hash_exists(&EG(included_files
), state
.cwd
,
1532 state
.cwd_length
+1);
1543 // Pretend the interpreter is running
1544 EG (in_execution
) = 1;
1546 int success
= zend_stream_open (Z_STRVAL_P (arg_file
), &handle TSRMLS_CC
);
1549 EG (in_execution
) = 0;
1550 EG (active_op_array
) = NULL
;
1552 if (success
!= SUCCESS
)
1558 // Check it hadnt been included already
1559 int once_success
= zend_hash_add_empty_element(&EG(included_files
),
1561 strlen (handle
.opened_path
)+1);
1563 if (once_success
!= SUCCESS
)
1565 ZVAL_BOOL (*p_result
, 1);
1570 if (!handle
.opened_path
)
1571 handle
.opened_path
= estrndup (Z_STRVAL_P(arg_file
), Z_STRLEN_P (arg_file
));
1574 success
= zend_execute_scripts (type TSRMLS_CC
, p_result
, 1, &handle
);
1575 assert (success
== SUCCESS
);
1576 zend_stream_close (&handle
);
1580 ZVAL_LONG (*p_result
, 1);
1588 php_error_docref (error_function
1590 (type
== ZEND_INCLUDE
) ? E_WARNING
: E_ERROR
,
1592 php_strip_url_passwd (Z_STRVAL_P (arg_file
)),
1593 STR_PRINT (PG (include_path
)));
1598 ZVAL_BOOL (*p_result
, 0);
1602 if (handle
.opened_path
)
1603 efree (handle
.opened_path
);
1604 zend_destroy_file_handle (&handle TSRMLS_CC
);
1607 if (arg
!= arg_file
)
1608 zval_ptr_dtor (&arg_file
);
1612 phc_builtin_include (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1614 include_backend ( arg
,
1619 "Failed opening '%s' for inclusion (include_path='%s')",
1625 phc_builtin_require (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1627 include_backend ( arg
,
1632 "Failed opening required '%s' (include_path='%s')",
1638 phc_builtin_include_once (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1640 include_backend ( arg
,
1645 "Failed opening '%s' for inclusion (include_path='%s')",
1646 "function.include_once"
1651 phc_builtin_require_once (zval
* arg
, zval
** p_result
, char *filename TSRMLS_DC
)
1653 include_backend ( arg
,
1658 "Failed opening required '%s' (include_path='%s')",
1659 "function.require_once"
1663 // END INCLUDED FILES
1665 static zend_fcall_info sanitizer_decodecharreferences_fci
;
1666 static zend_fcall_info_cache sanitizer_decodecharreferences_fcic
= {0,NULL
,NULL
,NULL
};
1667 static zend_fcall_info str_replace_fci
;
1668 static zend_fcall_info_cache str_replace_fcic
= {0,NULL
,NULL
,NULL
};
1669 // class CoreLinkFunctions
1671 // static function register($parser)
1673 // $TLE5 = NS_CATEGORY;
1674 // $TLE6 = 'CoreLinkFunctions';
1675 // $TLE7 = 'categoryLinkHook';
1677 // $TSa8 = (array) $TSa8;
1680 // $parser->setlinkhook($TLE5, $TSa8);
1684 // static function defaultlinkhook($parser, $holders, $markers, title $title, $titleText, &$displayText = NULL, &$leadingColon = False)
1686 // $TLE0 = isset($displayText);
1687 // if (TLE0) goto L27 else goto L28;
1689 // $TEF1 = $markers->findmarker($displayText);
1695 // $TLE10 = (bool) $TEF1;
1696 // if (TLE10) goto L30 else goto L31;
1698 // $displayText = $markers->expand($displayText);
1705 // $TLE12 = isset($displayText);
1706 // if (TLE12) goto L33 else goto L34;
1708 // $TEF2 = $displayText;
1711 // $TEF2 = $titleText;
1717 // $TLE16 = $holders->makeholder($title, $TEF2, $TLE13, $TLE14, $TLE15);
1720 // static function categorylinkhook($parser, $holders, $markers, title $title, $titleText, &$sortText = NULL, &$leadingColon = False)
1722 // global $wgContLang;
1723 // if (leadingColon) goto L36 else goto L37;
1731 // $TLE3 = isset($sortText);
1732 // if (TLE3) goto L39 else goto L40;
1734 // $TEF4 = $markers->findmarker($sortText);
1740 // $TLE18 = (bool) $TEF4;
1741 // if (TLE18) goto L42 else goto L43;
1743 // $sortText = $markers->expand($sortText);
1750 // $TLE20 = isset($sortText);
1751 // $TLE21 = !$TLE20;
1752 // if (TLE21) goto L45 else goto L46;
1754 // $sortText = $parser->getdefaultsort();
1759 // $sortText = sanitizer::decodecharreferences($sortText);
1763 // $sortText = str_replace($TLE22, $TLE23, $sortText);
1764 // $sortText = $wgContLang->convertcategorykey($sortText);
1765 // $TSt24 = $parser->mOutput;
1766 // $TLE25 = $title->getdbkey();
1767 // $TSt24->addcategory($TLE25, $sortText);
1772 // static function register($parser)
1774 // $TLE5 = NS_CATEGORY;
1775 // $TLE6 = 'CoreLinkFunctions';
1776 // $TLE7 = 'categoryLinkHook';
1778 // $TSa8 = (array) $TSa8;
1781 // $parser->setlinkhook($TLE5, $TSa8);
1785 PHP_METHOD(CoreLinkFunctions
, register)
1787 zval
* local_TLE5
= NULL
;
1788 zval
* local_TLE6
= NULL
;
1789 zval
* local_TLE7
= NULL
;
1790 zval
* local_TLE9
= NULL
;
1791 zval
* local_TSa8
= NULL
;
1792 zval
* local_parser
= NULL
;
1793 // Add all parameters as local variables
1795 int num_args
= ZEND_NUM_ARGS ();
1797 zend_get_parameters_array(0, num_args
, params
);
1799 params
[0]->refcount
++;
1800 if (local_parser
!= NULL
)
1802 zval_ptr_dtor (&local_parser
);
1804 local_parser
= params
[0];
1807 // $TLE5 = NS_CATEGORY;
1809 // No null-terminator in length for get_constant.
1810 // zend_get_constant always returns a copy of the constant.
1811 if (local_TLE5
== NULL
)
1813 local_TLE5
= EG (uninitialized_zval_ptr
);
1814 local_TLE5
->refcount
++;
1816 zval
** p_lhs
= &local_TLE5
;
1818 if (!(*p_lhs
)->is_ref
)
1820 zval_ptr_dtor (p_lhs
);
1821 get_constant ("NS_CATEGORY", 11, p_lhs TSRMLS_CC
);
1827 get_constant ("NS_CATEGORY", 11, p_lhs TSRMLS_CC
);
1828 overwrite_lhs_no_copy (*p_lhs
, constant
);
1829 safe_free_zval_ptr (constant
);
1832 phc_check_invariants (TSRMLS_C
);
1834 // $TLE6 = 'CoreLinkFunctions';
1836 if (local_TLE6
== NULL
)
1838 local_TLE6
= EG (uninitialized_zval_ptr
);
1839 local_TLE6
->refcount
++;
1841 zval
** p_lhs
= &local_TLE6
;
1844 if ((*p_lhs
)->is_ref
)
1846 // Always overwrite the current value
1852 ALLOC_INIT_ZVAL (value
);
1853 zval_ptr_dtor (p_lhs
);
1857 ZVAL_STRINGL(value
, "CoreLinkFunctions", 17, 1);
1859 phc_check_invariants (TSRMLS_C
);
1861 // $TLE7 = 'categoryLinkHook';
1863 if (local_TLE7
== NULL
)
1865 local_TLE7
= EG (uninitialized_zval_ptr
);
1866 local_TLE7
->refcount
++;
1868 zval
** p_lhs
= &local_TLE7
;
1871 if ((*p_lhs
)->is_ref
)
1873 // Always overwrite the current value
1879 ALLOC_INIT_ZVAL (value
);
1880 zval_ptr_dtor (p_lhs
);
1884 ZVAL_STRINGL(value
, "categoryLinkHook", 16, 1);
1886 phc_check_invariants (TSRMLS_C
);
1890 if (local_TSa8
!= NULL
)
1892 zval_ptr_dtor (&local_TSa8
);
1895 phc_check_invariants (TSRMLS_C
);
1897 // $TSa8 = (array) $TSa8;
1899 if (local_TSa8
== NULL
)
1901 local_TSa8
= EG (uninitialized_zval_ptr
);
1902 local_TSa8
->refcount
++;
1904 zval
** p_lhs
= &local_TSa8
;
1907 if (local_TSa8
== NULL
)
1908 rhs
= EG (uninitialized_zval_ptr
);
1914 if ((*p_lhs
)->is_ref
)
1915 overwrite_lhs (*p_lhs
, rhs
);
1918 zval_ptr_dtor (p_lhs
);
1921 // Take a copy of RHS for LHS
1922 *p_lhs
= zvp_clone_ex (rhs
);
1935 assert (IS_ARRAY
>= 0 && IS_ARRAY
<= 6);
1936 if ((*p_lhs
)->type
!= IS_ARRAY
)
1938 sep_copy_on_write (p_lhs
);
1939 convert_to_array (*p_lhs
);
1942 phc_check_invariants (TSRMLS_C
);
1946 if (local_TSa8
== NULL
)
1948 local_TSa8
= EG (uninitialized_zval_ptr
);
1949 local_TSa8
->refcount
++;
1951 zval
** p_array
= &local_TSa8
;
1953 // Push EG(uninit) and get a pointer to the symtable entry
1954 zval
** p_lhs
= push_and_index_ht (p_array TSRMLS_CC
);
1958 if (local_TLE6
== NULL
)
1959 rhs
= EG (uninitialized_zval_ptr
);
1964 write_var (p_lhs
, rhs
);
1966 // I think if this is NULL, then the LHS is a bool or similar, and you cant
1968 phc_check_invariants (TSRMLS_C
);
1972 if (local_TSa8
== NULL
)
1974 local_TSa8
= EG (uninitialized_zval_ptr
);
1975 local_TSa8
->refcount
++;
1977 zval
** p_array
= &local_TSa8
;
1979 // Push EG(uninit) and get a pointer to the symtable entry
1980 zval
** p_lhs
= push_and_index_ht (p_array TSRMLS_CC
);
1984 if (local_TLE7
== NULL
)
1985 rhs
= EG (uninitialized_zval_ptr
);
1990 write_var (p_lhs
, rhs
);
1992 // I think if this is NULL, then the LHS is a bool or similar, and you cant
1994 phc_check_invariants (TSRMLS_C
);
1996 // $parser->setlinkhook($TLE5, $TSa8);
1998 if (local_parser
== NULL
)
2000 local_parser
= EG (uninitialized_zval_ptr
);
2001 local_parser
->refcount
++;
2003 zval
** p_obj
= &local_parser
;
2005 zend_fcall_info fci_object
;
2006 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
2007 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "setlinkhook", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 9 TSRMLS_CC
);
2008 zend_function
* signature
= fcic_object
.function_handler
;
2009 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
2013 // TODO: find names to replace index
2016 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
2020 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
2023 // TODO: find names to replace index
2026 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
2030 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
2035 // Setup array of arguments
2036 // TODO: i think arrays of size 0 is an error
2039 zval
** args_ind
[2];
2042 destruct
[af_index
] = 0;
2043 if (by_ref
[af_index
])
2045 if (local_TLE5
== NULL
)
2047 local_TLE5
= EG (uninitialized_zval_ptr
);
2048 local_TLE5
->refcount
++;
2050 zval
** p_arg
= &local_TLE5
;
2052 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
2053 assert (!in_copy_on_write (*args_ind
[af_index
]));
2054 args
[af_index
] = *args_ind
[af_index
];
2059 if (local_TLE5
== NULL
)
2060 arg
= EG (uninitialized_zval_ptr
);
2064 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
2065 args_ind
[af_index
] = &args
[af_index
];
2068 destruct
[af_index
] = 0;
2069 if (by_ref
[af_index
])
2071 if (local_TSa8
== NULL
)
2073 local_TSa8
= EG (uninitialized_zval_ptr
);
2074 local_TSa8
->refcount
++;
2076 zval
** p_arg
= &local_TSa8
;
2078 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
2079 assert (!in_copy_on_write (*args_ind
[af_index
]));
2080 args
[af_index
] = *args_ind
[af_index
];
2085 if (local_TSa8
== NULL
)
2086 arg
= EG (uninitialized_zval_ptr
);
2090 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
2091 args_ind
[af_index
] = &args
[af_index
];
2096 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 9, NULL TSRMLS_CC
);
2098 // save existing parameters, in case of recursion
2099 int param_count_save
= fci_object
.param_count
;
2100 zval
*** params_save
= fci_object
.params
;
2101 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
2106 fci_object
.params
= args_ind
;
2107 fci_object
.param_count
= 2;
2108 fci_object
.retval_ptr_ptr
= &rhs
;
2110 // call the function
2111 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
2112 assert(success
== SUCCESS
);
2115 fci_object
.params
= params_save
;
2116 fci_object
.param_count
= param_count_save
;
2117 fci_object
.retval_ptr_ptr
= retval_save
;
2120 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
2123 for (i
= 0; i
< 2; i
++)
2127 assert (destruct
[i
]);
2128 zval_ptr_dtor (args_ind
[i
]);
2133 // When the Zend engine returns by reference, it allocates a zval into
2134 // retval_ptr_ptr. To return by reference, the callee writes into the
2135 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
2136 // not actually return anything). So the zval returned - whether we return
2137 // it, or it is the allocated zval - has a refcount of 1.
2139 // The caller is responsible for cleaning that up (note, this is unaffected
2140 // by whether it is added to some COW set).
2142 // For reasons unknown, the Zend API resets the refcount and is_ref fields
2143 // of the return value after the function returns (unless the callee is
2144 // interpreted). If the function is supposed to return by reference, this
2145 // loses the refcount. This only happens when non-interpreted code is
2146 // called. We work around it, when compiled code is called, by saving the
2147 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
2148 // that we may create an error if our code is called by a callback, and
2149 // returns by reference, and the callback returns by reference. At least
2150 // this is an obscure case.
2151 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
2153 assert (rhs
!= EG(uninitialized_zval_ptr
));
2155 if (saved_refcount
!= 0)
2157 rhs
->refcount
= saved_refcount
;
2161 saved_refcount
= 0; // for 'obscure cases'
2165 zval_ptr_dtor (&rhs
);
2166 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
2167 zval_ptr_dtor (&rhs
);
2169 phc_check_invariants (TSRMLS_C
);
2173 if (local_TLE9
== NULL
)
2175 local_TLE9
= EG (uninitialized_zval_ptr
);
2176 local_TLE9
->refcount
++;
2178 zval
** p_lhs
= &local_TLE9
;
2181 if ((*p_lhs
)->is_ref
)
2183 // Always overwrite the current value
2189 ALLOC_INIT_ZVAL (value
);
2190 zval_ptr_dtor (p_lhs
);
2194 ZVAL_BOOL (value
, 1);
2196 phc_check_invariants (TSRMLS_C
);
2201 if (local_TLE9
== NULL
)
2202 rhs
= EG (uninitialized_zval_ptr
);
2206 // Run-time return by reference has different semantics to compile-time.
2207 // If the function has CTRBR and RTRBR, the the assignment will be
2208 // reference. If one or the other is return-by-copy, the result will be
2209 // by copy. Its a question of whether its separated at return-time (which
2210 // we do here) or at the call-site.
2211 return_value
->value
= rhs
->value
;
2212 return_value
->type
= rhs
->type
;
2213 zval_copy_ctor (return_value
);
2214 goto end_of_function
;
2215 phc_check_invariants (TSRMLS_C
);
2218 end_of_function
:__attribute__((unused
));
2219 if (local_TLE5
!= NULL
)
2221 zval_ptr_dtor (&local_TLE5
);
2223 if (local_TLE6
!= NULL
)
2225 zval_ptr_dtor (&local_TLE6
);
2227 if (local_TLE7
!= NULL
)
2229 zval_ptr_dtor (&local_TLE7
);
2231 if (local_TLE9
!= NULL
)
2233 zval_ptr_dtor (&local_TLE9
);
2235 if (local_TSa8
!= NULL
)
2237 zval_ptr_dtor (&local_TSa8
);
2239 if (local_parser
!= NULL
)
2241 zval_ptr_dtor (&local_parser
);
2244 // static function defaultlinkhook($parser, $holders, $markers, title $title, $titleText, &$displayText = NULL, &$leadingColon = False)
2246 // $TLE0 = isset($displayText);
2247 // if (TLE0) goto L27 else goto L28;
2249 // $TEF1 = $markers->findmarker($displayText);
2255 // $TLE10 = (bool) $TEF1;
2256 // if (TLE10) goto L30 else goto L31;
2258 // $displayText = $markers->expand($displayText);
2265 // $TLE12 = isset($displayText);
2266 // if (TLE12) goto L33 else goto L34;
2268 // $TEF2 = $displayText;
2271 // $TEF2 = $titleText;
2277 // $TLE16 = $holders->makeholder($title, $TEF2, $TLE13, $TLE14, $TLE15);
2280 PHP_METHOD(CoreLinkFunctions
, defaultlinkhook
)
2282 zval
* local_TEF1
= NULL
;
2283 zval
* local_TEF2
= NULL
;
2284 zval
* local_TLE0
= NULL
;
2285 zval
* local_TLE10
= NULL
;
2286 zval
* local_TLE11
= NULL
;
2287 zval
* local_TLE12
= NULL
;
2288 zval
* local_TLE13
= NULL
;
2289 zval
* local_TLE14
= NULL
;
2290 zval
* local_TLE15
= NULL
;
2291 zval
* local_TLE16
= NULL
;
2292 zval
* local_displayText
= NULL
;
2293 zval
* local_holders
= NULL
;
2294 zval
* local_leadingColon
= NULL
;
2295 zval
* local_markers
= NULL
;
2296 zval
* local_parser
= NULL
;
2297 zval
* local_title
= NULL
;
2298 zval
* local_titleText
= NULL
;
2299 // Add all parameters as local variables
2301 int num_args
= ZEND_NUM_ARGS ();
2303 zend_get_parameters_array(0, num_args
, params
);
2305 params
[0]->refcount
++;
2306 if (local_parser
!= NULL
)
2308 zval_ptr_dtor (&local_parser
);
2310 local_parser
= params
[0];
2312 params
[1]->refcount
++;
2313 if (local_holders
!= NULL
)
2315 zval_ptr_dtor (&local_holders
);
2317 local_holders
= params
[1];
2319 params
[2]->refcount
++;
2320 if (local_markers
!= NULL
)
2322 zval_ptr_dtor (&local_markers
);
2324 local_markers
= params
[2];
2326 params
[3]->refcount
++;
2327 if (local_title
!= NULL
)
2329 zval_ptr_dtor (&local_title
);
2331 local_title
= params
[3];
2333 params
[4]->refcount
++;
2334 if (local_titleText
!= NULL
)
2336 zval_ptr_dtor (&local_titleText
);
2338 local_titleText
= params
[4];
2342 zval
* default_value
;
2344 zval
* local___static_value__
= NULL
;
2345 // $__static_value__ = NULL;
2347 if (local___static_value__
== NULL
)
2349 local___static_value__
= EG (uninitialized_zval_ptr
);
2350 local___static_value__
->refcount
++;
2352 zval
** p_lhs
= &local___static_value__
;
2355 if ((*p_lhs
)->is_ref
)
2357 // Always overwrite the current value
2363 ALLOC_INIT_ZVAL (value
);
2364 zval_ptr_dtor (p_lhs
);
2370 phc_check_invariants (TSRMLS_C
);
2372 default_value
= local___static_value__
;
2373 assert(!default_value
->is_ref
);
2374 default_value
->refcount
++;
2375 if (local___static_value__
!= NULL
)
2377 zval_ptr_dtor (&local___static_value__
);
2380 default_value
->refcount
--;
2381 params
[5] = default_value
;
2383 params
[5]->refcount
++;
2384 if (local_displayText
!= NULL
)
2386 zval_ptr_dtor (&local_displayText
);
2388 local_displayText
= params
[5];
2392 zval
* default_value
;
2394 zval
* local___static_value__
= NULL
;
2395 // $__static_value__ = False;
2397 if (local___static_value__
== NULL
)
2399 local___static_value__
= EG (uninitialized_zval_ptr
);
2400 local___static_value__
->refcount
++;
2402 zval
** p_lhs
= &local___static_value__
;
2405 if ((*p_lhs
)->is_ref
)
2407 // Always overwrite the current value
2413 ALLOC_INIT_ZVAL (value
);
2414 zval_ptr_dtor (p_lhs
);
2418 ZVAL_BOOL (value
, 0);
2420 phc_check_invariants (TSRMLS_C
);
2422 default_value
= local___static_value__
;
2423 assert(!default_value
->is_ref
);
2424 default_value
->refcount
++;
2425 if (local___static_value__
!= NULL
)
2427 zval_ptr_dtor (&local___static_value__
);
2430 default_value
->refcount
--;
2431 params
[6] = default_value
;
2433 params
[6]->refcount
++;
2434 if (local_leadingColon
!= NULL
)
2436 zval_ptr_dtor (&local_leadingColon
);
2438 local_leadingColon
= params
[6];
2441 // $TLE0 = isset($displayText);
2443 if (local_TLE0
== NULL
)
2445 local_TLE0
= EG (uninitialized_zval_ptr
);
2446 local_TLE0
->refcount
++;
2448 zval
** p_lhs
= &local_TLE0
;
2450 if ((*p_lhs
)->is_ref
)
2452 // Always overwrite the current value
2458 ALLOC_INIT_ZVAL (value
);
2459 zval_ptr_dtor (p_lhs
);
2462 ZVAL_BOOL(value
, local_displayText
!= NULL
&& !ZVAL_IS_NULL(local_displayText
));
2463 phc_check_invariants (TSRMLS_C
);
2465 // if (TLE0) goto L27 else goto L28;
2468 if (local_TLE0
== NULL
)
2469 p_cond
= EG (uninitialized_zval_ptr
);
2471 p_cond
= local_TLE0
;
2473 zend_bool bcond
= zend_is_true (p_cond
);
2478 phc_check_invariants (TSRMLS_C
);
2482 // $TEF1 = $markers->findmarker($displayText);
2484 if (local_markers
== NULL
)
2486 local_markers
= EG (uninitialized_zval_ptr
);
2487 local_markers
->refcount
++;
2489 zval
** p_obj
= &local_markers
;
2491 zend_fcall_info fci_object
;
2492 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
2493 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "findmarker", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 15 TSRMLS_CC
);
2494 zend_function
* signature
= fcic_object
.function_handler
;
2495 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
2499 // TODO: find names to replace index
2502 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
2506 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
2511 // Setup array of arguments
2512 // TODO: i think arrays of size 0 is an error
2515 zval
** args_ind
[1];
2518 destruct
[af_index
] = 0;
2519 if (by_ref
[af_index
])
2521 if (local_displayText
== NULL
)
2523 local_displayText
= EG (uninitialized_zval_ptr
);
2524 local_displayText
->refcount
++;
2526 zval
** p_arg
= &local_displayText
;
2528 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
2529 assert (!in_copy_on_write (*args_ind
[af_index
]));
2530 args
[af_index
] = *args_ind
[af_index
];
2535 if (local_displayText
== NULL
)
2536 arg
= EG (uninitialized_zval_ptr
);
2538 arg
= local_displayText
;
2540 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
2541 args_ind
[af_index
] = &args
[af_index
];
2546 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 15, NULL TSRMLS_CC
);
2548 // save existing parameters, in case of recursion
2549 int param_count_save
= fci_object
.param_count
;
2550 zval
*** params_save
= fci_object
.params
;
2551 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
2556 fci_object
.params
= args_ind
;
2557 fci_object
.param_count
= 1;
2558 fci_object
.retval_ptr_ptr
= &rhs
;
2560 // call the function
2561 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
2562 assert(success
== SUCCESS
);
2565 fci_object
.params
= params_save
;
2566 fci_object
.param_count
= param_count_save
;
2567 fci_object
.retval_ptr_ptr
= retval_save
;
2570 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
2573 for (i
= 0; i
< 1; i
++)
2577 assert (destruct
[i
]);
2578 zval_ptr_dtor (args_ind
[i
]);
2583 // When the Zend engine returns by reference, it allocates a zval into
2584 // retval_ptr_ptr. To return by reference, the callee writes into the
2585 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
2586 // not actually return anything). So the zval returned - whether we return
2587 // it, or it is the allocated zval - has a refcount of 1.
2589 // The caller is responsible for cleaning that up (note, this is unaffected
2590 // by whether it is added to some COW set).
2592 // For reasons unknown, the Zend API resets the refcount and is_ref fields
2593 // of the return value after the function returns (unless the callee is
2594 // interpreted). If the function is supposed to return by reference, this
2595 // loses the refcount. This only happens when non-interpreted code is
2596 // called. We work around it, when compiled code is called, by saving the
2597 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
2598 // that we may create an error if our code is called by a callback, and
2599 // returns by reference, and the callback returns by reference. At least
2600 // this is an obscure case.
2601 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
2603 assert (rhs
!= EG(uninitialized_zval_ptr
));
2605 if (saved_refcount
!= 0)
2607 rhs
->refcount
= saved_refcount
;
2611 saved_refcount
= 0; // for 'obscure cases'
2613 if (local_TEF1
== NULL
)
2615 local_TEF1
= EG (uninitialized_zval_ptr
);
2616 local_TEF1
->refcount
++;
2618 zval
** p_lhs
= &local_TEF1
;
2620 write_var (p_lhs
, rhs
);
2623 zval_ptr_dtor (&rhs
);
2624 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
2625 zval_ptr_dtor (&rhs
);
2627 phc_check_invariants (TSRMLS_C
);
2632 phc_check_invariants (TSRMLS_C
);
2638 if (local_TEF1
== NULL
)
2640 local_TEF1
= EG (uninitialized_zval_ptr
);
2641 local_TEF1
->refcount
++;
2643 zval
** p_lhs
= &local_TEF1
;
2646 if (local_TLE0
== NULL
)
2647 rhs
= EG (uninitialized_zval_ptr
);
2653 if ((*p_lhs
)->is_ref
)
2654 overwrite_lhs (*p_lhs
, rhs
);
2657 zval_ptr_dtor (p_lhs
);
2660 // Take a copy of RHS for LHS
2661 *p_lhs
= zvp_clone_ex (rhs
);
2673 phc_check_invariants (TSRMLS_C
);
2678 phc_check_invariants (TSRMLS_C
);
2682 // $TLE10 = (bool) $TEF1;
2684 if (local_TLE10
== NULL
)
2686 local_TLE10
= EG (uninitialized_zval_ptr
);
2687 local_TLE10
->refcount
++;
2689 zval
** p_lhs
= &local_TLE10
;
2692 if (local_TEF1
== NULL
)
2693 rhs
= EG (uninitialized_zval_ptr
);
2699 if ((*p_lhs
)->is_ref
)
2700 overwrite_lhs (*p_lhs
, rhs
);
2703 zval_ptr_dtor (p_lhs
);
2706 // Take a copy of RHS for LHS
2707 *p_lhs
= zvp_clone_ex (rhs
);
2720 assert (IS_BOOL
>= 0 && IS_BOOL
<= 6);
2721 if ((*p_lhs
)->type
!= IS_BOOL
)
2723 sep_copy_on_write (p_lhs
);
2724 convert_to_boolean (*p_lhs
);
2727 phc_check_invariants (TSRMLS_C
);
2729 // if (TLE10) goto L30 else goto L31;
2732 if (local_TLE10
== NULL
)
2733 p_cond
= EG (uninitialized_zval_ptr
);
2735 p_cond
= local_TLE10
;
2737 zend_bool bcond
= zend_is_true (p_cond
);
2742 phc_check_invariants (TSRMLS_C
);
2746 // $displayText = $markers->expand($displayText);
2748 if (local_markers
== NULL
)
2750 local_markers
= EG (uninitialized_zval_ptr
);
2751 local_markers
->refcount
++;
2753 zval
** p_obj
= &local_markers
;
2755 zend_fcall_info fci_object
;
2756 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
2757 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "expand", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 19 TSRMLS_CC
);
2758 zend_function
* signature
= fcic_object
.function_handler
;
2759 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
2763 // TODO: find names to replace index
2766 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
2770 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
2775 // Setup array of arguments
2776 // TODO: i think arrays of size 0 is an error
2779 zval
** args_ind
[1];
2782 destruct
[af_index
] = 0;
2783 if (by_ref
[af_index
])
2785 if (local_displayText
== NULL
)
2787 local_displayText
= EG (uninitialized_zval_ptr
);
2788 local_displayText
->refcount
++;
2790 zval
** p_arg
= &local_displayText
;
2792 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
2793 assert (!in_copy_on_write (*args_ind
[af_index
]));
2794 args
[af_index
] = *args_ind
[af_index
];
2799 if (local_displayText
== NULL
)
2800 arg
= EG (uninitialized_zval_ptr
);
2802 arg
= local_displayText
;
2804 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
2805 args_ind
[af_index
] = &args
[af_index
];
2810 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 19, NULL TSRMLS_CC
);
2812 // save existing parameters, in case of recursion
2813 int param_count_save
= fci_object
.param_count
;
2814 zval
*** params_save
= fci_object
.params
;
2815 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
2820 fci_object
.params
= args_ind
;
2821 fci_object
.param_count
= 1;
2822 fci_object
.retval_ptr_ptr
= &rhs
;
2824 // call the function
2825 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
2826 assert(success
== SUCCESS
);
2829 fci_object
.params
= params_save
;
2830 fci_object
.param_count
= param_count_save
;
2831 fci_object
.retval_ptr_ptr
= retval_save
;
2834 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
2837 for (i
= 0; i
< 1; i
++)
2841 assert (destruct
[i
]);
2842 zval_ptr_dtor (args_ind
[i
]);
2847 // When the Zend engine returns by reference, it allocates a zval into
2848 // retval_ptr_ptr. To return by reference, the callee writes into the
2849 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
2850 // not actually return anything). So the zval returned - whether we return
2851 // it, or it is the allocated zval - has a refcount of 1.
2853 // The caller is responsible for cleaning that up (note, this is unaffected
2854 // by whether it is added to some COW set).
2856 // For reasons unknown, the Zend API resets the refcount and is_ref fields
2857 // of the return value after the function returns (unless the callee is
2858 // interpreted). If the function is supposed to return by reference, this
2859 // loses the refcount. This only happens when non-interpreted code is
2860 // called. We work around it, when compiled code is called, by saving the
2861 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
2862 // that we may create an error if our code is called by a callback, and
2863 // returns by reference, and the callback returns by reference. At least
2864 // this is an obscure case.
2865 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
2867 assert (rhs
!= EG(uninitialized_zval_ptr
));
2869 if (saved_refcount
!= 0)
2871 rhs
->refcount
= saved_refcount
;
2875 saved_refcount
= 0; // for 'obscure cases'
2877 if (local_displayText
== NULL
)
2879 local_displayText
= EG (uninitialized_zval_ptr
);
2880 local_displayText
->refcount
++;
2882 zval
** p_lhs
= &local_displayText
;
2884 write_var (p_lhs
, rhs
);
2887 zval_ptr_dtor (&rhs
);
2888 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
2889 zval_ptr_dtor (&rhs
);
2891 phc_check_invariants (TSRMLS_C
);
2895 if (local_TLE11
== NULL
)
2897 local_TLE11
= EG (uninitialized_zval_ptr
);
2898 local_TLE11
->refcount
++;
2900 zval
** p_lhs
= &local_TLE11
;
2903 if ((*p_lhs
)->is_ref
)
2905 // Always overwrite the current value
2911 ALLOC_INIT_ZVAL (value
);
2912 zval_ptr_dtor (p_lhs
);
2916 ZVAL_BOOL (value
, 0);
2918 phc_check_invariants (TSRMLS_C
);
2923 if (local_TLE11
== NULL
)
2924 rhs
= EG (uninitialized_zval_ptr
);
2928 // Run-time return by reference has different semantics to compile-time.
2929 // If the function has CTRBR and RTRBR, the the assignment will be
2930 // reference. If one or the other is return-by-copy, the result will be
2931 // by copy. Its a question of whether its separated at return-time (which
2932 // we do here) or at the call-site.
2933 return_value
->value
= rhs
->value
;
2934 return_value
->type
= rhs
->type
;
2935 zval_copy_ctor (return_value
);
2936 goto end_of_function
;
2937 phc_check_invariants (TSRMLS_C
);
2942 phc_check_invariants (TSRMLS_C
);
2949 phc_check_invariants (TSRMLS_C
);
2953 // $TLE12 = isset($displayText);
2955 if (local_TLE12
== NULL
)
2957 local_TLE12
= EG (uninitialized_zval_ptr
);
2958 local_TLE12
->refcount
++;
2960 zval
** p_lhs
= &local_TLE12
;
2962 if ((*p_lhs
)->is_ref
)
2964 // Always overwrite the current value
2970 ALLOC_INIT_ZVAL (value
);
2971 zval_ptr_dtor (p_lhs
);
2974 ZVAL_BOOL(value
, local_displayText
!= NULL
&& !ZVAL_IS_NULL(local_displayText
));
2975 phc_check_invariants (TSRMLS_C
);
2977 // if (TLE12) goto L33 else goto L34;
2980 if (local_TLE12
== NULL
)
2981 p_cond
= EG (uninitialized_zval_ptr
);
2983 p_cond
= local_TLE12
;
2985 zend_bool bcond
= zend_is_true (p_cond
);
2990 phc_check_invariants (TSRMLS_C
);
2994 // $TEF2 = $displayText;
2996 if (local_TEF2
== NULL
)
2998 local_TEF2
= EG (uninitialized_zval_ptr
);
2999 local_TEF2
->refcount
++;
3001 zval
** p_lhs
= &local_TEF2
;
3004 if (local_displayText
== NULL
)
3005 rhs
= EG (uninitialized_zval_ptr
);
3007 rhs
= local_displayText
;
3011 if ((*p_lhs
)->is_ref
)
3012 overwrite_lhs (*p_lhs
, rhs
);
3015 zval_ptr_dtor (p_lhs
);
3018 // Take a copy of RHS for LHS
3019 *p_lhs
= zvp_clone_ex (rhs
);
3031 phc_check_invariants (TSRMLS_C
);
3036 phc_check_invariants (TSRMLS_C
);
3040 // $TEF2 = $titleText;
3042 if (local_TEF2
== NULL
)
3044 local_TEF2
= EG (uninitialized_zval_ptr
);
3045 local_TEF2
->refcount
++;
3047 zval
** p_lhs
= &local_TEF2
;
3050 if (local_titleText
== NULL
)
3051 rhs
= EG (uninitialized_zval_ptr
);
3053 rhs
= local_titleText
;
3057 if ((*p_lhs
)->is_ref
)
3058 overwrite_lhs (*p_lhs
, rhs
);
3061 zval_ptr_dtor (p_lhs
);
3064 // Take a copy of RHS for LHS
3065 *p_lhs
= zvp_clone_ex (rhs
);
3077 phc_check_invariants (TSRMLS_C
);
3082 phc_check_invariants (TSRMLS_C
);
3088 if (local_TLE13
== NULL
)
3090 local_TLE13
= EG (uninitialized_zval_ptr
);
3091 local_TLE13
->refcount
++;
3093 zval
** p_lhs
= &local_TLE13
;
3096 if ((*p_lhs
)->is_ref
)
3098 // Always overwrite the current value
3104 ALLOC_INIT_ZVAL (value
);
3105 zval_ptr_dtor (p_lhs
);
3109 ZVAL_STRINGL(value
, "", 0, 1);
3111 phc_check_invariants (TSRMLS_C
);
3115 if (local_TLE14
== NULL
)
3117 local_TLE14
= EG (uninitialized_zval_ptr
);
3118 local_TLE14
->refcount
++;
3120 zval
** p_lhs
= &local_TLE14
;
3123 if ((*p_lhs
)->is_ref
)
3125 // Always overwrite the current value
3131 ALLOC_INIT_ZVAL (value
);
3132 zval_ptr_dtor (p_lhs
);
3136 ZVAL_STRINGL(value
, "", 0, 1);
3138 phc_check_invariants (TSRMLS_C
);
3142 if (local_TLE15
== NULL
)
3144 local_TLE15
= EG (uninitialized_zval_ptr
);
3145 local_TLE15
->refcount
++;
3147 zval
** p_lhs
= &local_TLE15
;
3150 if ((*p_lhs
)->is_ref
)
3152 // Always overwrite the current value
3158 ALLOC_INIT_ZVAL (value
);
3159 zval_ptr_dtor (p_lhs
);
3163 ZVAL_STRINGL(value
, "", 0, 1);
3165 phc_check_invariants (TSRMLS_C
);
3167 // $TLE16 = $holders->makeholder($title, $TEF2, $TLE13, $TLE14, $TLE15);
3169 if (local_holders
== NULL
)
3171 local_holders
= EG (uninitialized_zval_ptr
);
3172 local_holders
->refcount
++;
3174 zval
** p_obj
= &local_holders
;
3176 zend_fcall_info fci_object
;
3177 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
3178 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "makeholder", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 23 TSRMLS_CC
);
3179 zend_function
* signature
= fcic_object
.function_handler
;
3180 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
3184 // TODO: find names to replace index
3187 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
3191 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
3194 // TODO: find names to replace index
3197 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
3201 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
3204 // TODO: find names to replace index
3207 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
3211 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
3214 // TODO: find names to replace index
3217 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
3221 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
3224 // TODO: find names to replace index
3227 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
3231 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
3236 // Setup array of arguments
3237 // TODO: i think arrays of size 0 is an error
3240 zval
** args_ind
[5];
3243 destruct
[af_index
] = 0;
3244 if (by_ref
[af_index
])
3246 if (local_title
== NULL
)
3248 local_title
= EG (uninitialized_zval_ptr
);
3249 local_title
->refcount
++;
3251 zval
** p_arg
= &local_title
;
3253 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
3254 assert (!in_copy_on_write (*args_ind
[af_index
]));
3255 args
[af_index
] = *args_ind
[af_index
];
3260 if (local_title
== NULL
)
3261 arg
= EG (uninitialized_zval_ptr
);
3265 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
3266 args_ind
[af_index
] = &args
[af_index
];
3269 destruct
[af_index
] = 0;
3270 if (by_ref
[af_index
])
3272 if (local_TEF2
== NULL
)
3274 local_TEF2
= EG (uninitialized_zval_ptr
);
3275 local_TEF2
->refcount
++;
3277 zval
** p_arg
= &local_TEF2
;
3279 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
3280 assert (!in_copy_on_write (*args_ind
[af_index
]));
3281 args
[af_index
] = *args_ind
[af_index
];
3286 if (local_TEF2
== NULL
)
3287 arg
= EG (uninitialized_zval_ptr
);
3291 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
3292 args_ind
[af_index
] = &args
[af_index
];
3295 destruct
[af_index
] = 0;
3296 if (by_ref
[af_index
])
3298 if (local_TLE13
== NULL
)
3300 local_TLE13
= EG (uninitialized_zval_ptr
);
3301 local_TLE13
->refcount
++;
3303 zval
** p_arg
= &local_TLE13
;
3305 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
3306 assert (!in_copy_on_write (*args_ind
[af_index
]));
3307 args
[af_index
] = *args_ind
[af_index
];
3312 if (local_TLE13
== NULL
)
3313 arg
= EG (uninitialized_zval_ptr
);
3317 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
3318 args_ind
[af_index
] = &args
[af_index
];
3321 destruct
[af_index
] = 0;
3322 if (by_ref
[af_index
])
3324 if (local_TLE14
== NULL
)
3326 local_TLE14
= EG (uninitialized_zval_ptr
);
3327 local_TLE14
->refcount
++;
3329 zval
** p_arg
= &local_TLE14
;
3331 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
3332 assert (!in_copy_on_write (*args_ind
[af_index
]));
3333 args
[af_index
] = *args_ind
[af_index
];
3338 if (local_TLE14
== NULL
)
3339 arg
= EG (uninitialized_zval_ptr
);
3343 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
3344 args_ind
[af_index
] = &args
[af_index
];
3347 destruct
[af_index
] = 0;
3348 if (by_ref
[af_index
])
3350 if (local_TLE15
== NULL
)
3352 local_TLE15
= EG (uninitialized_zval_ptr
);
3353 local_TLE15
->refcount
++;
3355 zval
** p_arg
= &local_TLE15
;
3357 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
3358 assert (!in_copy_on_write (*args_ind
[af_index
]));
3359 args
[af_index
] = *args_ind
[af_index
];
3364 if (local_TLE15
== NULL
)
3365 arg
= EG (uninitialized_zval_ptr
);
3369 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
3370 args_ind
[af_index
] = &args
[af_index
];
3375 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 23, NULL TSRMLS_CC
);
3377 // save existing parameters, in case of recursion
3378 int param_count_save
= fci_object
.param_count
;
3379 zval
*** params_save
= fci_object
.params
;
3380 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
3385 fci_object
.params
= args_ind
;
3386 fci_object
.param_count
= 5;
3387 fci_object
.retval_ptr_ptr
= &rhs
;
3389 // call the function
3390 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
3391 assert(success
== SUCCESS
);
3394 fci_object
.params
= params_save
;
3395 fci_object
.param_count
= param_count_save
;
3396 fci_object
.retval_ptr_ptr
= retval_save
;
3399 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
3402 for (i
= 0; i
< 5; i
++)
3406 assert (destruct
[i
]);
3407 zval_ptr_dtor (args_ind
[i
]);
3412 // When the Zend engine returns by reference, it allocates a zval into
3413 // retval_ptr_ptr. To return by reference, the callee writes into the
3414 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
3415 // not actually return anything). So the zval returned - whether we return
3416 // it, or it is the allocated zval - has a refcount of 1.
3418 // The caller is responsible for cleaning that up (note, this is unaffected
3419 // by whether it is added to some COW set).
3421 // For reasons unknown, the Zend API resets the refcount and is_ref fields
3422 // of the return value after the function returns (unless the callee is
3423 // interpreted). If the function is supposed to return by reference, this
3424 // loses the refcount. This only happens when non-interpreted code is
3425 // called. We work around it, when compiled code is called, by saving the
3426 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
3427 // that we may create an error if our code is called by a callback, and
3428 // returns by reference, and the callback returns by reference. At least
3429 // this is an obscure case.
3430 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
3432 assert (rhs
!= EG(uninitialized_zval_ptr
));
3434 if (saved_refcount
!= 0)
3436 rhs
->refcount
= saved_refcount
;
3440 saved_refcount
= 0; // for 'obscure cases'
3442 if (local_TLE16
== NULL
)
3444 local_TLE16
= EG (uninitialized_zval_ptr
);
3445 local_TLE16
->refcount
++;
3447 zval
** p_lhs
= &local_TLE16
;
3449 write_var (p_lhs
, rhs
);
3452 zval_ptr_dtor (&rhs
);
3453 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
3454 zval_ptr_dtor (&rhs
);
3456 phc_check_invariants (TSRMLS_C
);
3461 if (local_TLE16
== NULL
)
3462 rhs
= EG (uninitialized_zval_ptr
);
3466 // Run-time return by reference has different semantics to compile-time.
3467 // If the function has CTRBR and RTRBR, the the assignment will be
3468 // reference. If one or the other is return-by-copy, the result will be
3469 // by copy. Its a question of whether its separated at return-time (which
3470 // we do here) or at the call-site.
3471 return_value
->value
= rhs
->value
;
3472 return_value
->type
= rhs
->type
;
3473 zval_copy_ctor (return_value
);
3474 goto end_of_function
;
3475 phc_check_invariants (TSRMLS_C
);
3478 end_of_function
:__attribute__((unused
));
3479 if (local_TEF1
!= NULL
)
3481 zval_ptr_dtor (&local_TEF1
);
3483 if (local_TEF2
!= NULL
)
3485 zval_ptr_dtor (&local_TEF2
);
3487 if (local_TLE0
!= NULL
)
3489 zval_ptr_dtor (&local_TLE0
);
3491 if (local_TLE10
!= NULL
)
3493 zval_ptr_dtor (&local_TLE10
);
3495 if (local_TLE11
!= NULL
)
3497 zval_ptr_dtor (&local_TLE11
);
3499 if (local_TLE12
!= NULL
)
3501 zval_ptr_dtor (&local_TLE12
);
3503 if (local_TLE13
!= NULL
)
3505 zval_ptr_dtor (&local_TLE13
);
3507 if (local_TLE14
!= NULL
)
3509 zval_ptr_dtor (&local_TLE14
);
3511 if (local_TLE15
!= NULL
)
3513 zval_ptr_dtor (&local_TLE15
);
3515 if (local_TLE16
!= NULL
)
3517 zval_ptr_dtor (&local_TLE16
);
3519 if (local_displayText
!= NULL
)
3521 zval_ptr_dtor (&local_displayText
);
3523 if (local_holders
!= NULL
)
3525 zval_ptr_dtor (&local_holders
);
3527 if (local_leadingColon
!= NULL
)
3529 zval_ptr_dtor (&local_leadingColon
);
3531 if (local_markers
!= NULL
)
3533 zval_ptr_dtor (&local_markers
);
3535 if (local_parser
!= NULL
)
3537 zval_ptr_dtor (&local_parser
);
3539 if (local_title
!= NULL
)
3541 zval_ptr_dtor (&local_title
);
3543 if (local_titleText
!= NULL
)
3545 zval_ptr_dtor (&local_titleText
);
3548 // static function categorylinkhook($parser, $holders, $markers, title $title, $titleText, &$sortText = NULL, &$leadingColon = False)
3550 // global $wgContLang;
3551 // if (leadingColon) goto L36 else goto L37;
3559 // $TLE3 = isset($sortText);
3560 // if (TLE3) goto L39 else goto L40;
3562 // $TEF4 = $markers->findmarker($sortText);
3568 // $TLE18 = (bool) $TEF4;
3569 // if (TLE18) goto L42 else goto L43;
3571 // $sortText = $markers->expand($sortText);
3578 // $TLE20 = isset($sortText);
3579 // $TLE21 = !$TLE20;
3580 // if (TLE21) goto L45 else goto L46;
3582 // $sortText = $parser->getdefaultsort();
3587 // $sortText = sanitizer::decodecharreferences($sortText);
3591 // $sortText = str_replace($TLE22, $TLE23, $sortText);
3592 // $sortText = $wgContLang->convertcategorykey($sortText);
3593 // $TSt24 = $parser->mOutput;
3594 // $TLE25 = $title->getdbkey();
3595 // $TSt24->addcategory($TLE25, $sortText);
3599 PHP_METHOD(CoreLinkFunctions
, categorylinkhook
)
3601 zval
* local_TEF4
= NULL
;
3602 zval
* local_TLE17
= NULL
;
3603 zval
* local_TLE18
= NULL
;
3604 zval
* local_TLE19
= NULL
;
3605 zval
* local_TLE20
= NULL
;
3606 zval
* local_TLE21
= NULL
;
3607 zval
* local_TLE22
= NULL
;
3608 zval
* local_TLE23
= NULL
;
3609 zval
* local_TLE25
= NULL
;
3610 zval
* local_TLE26
= NULL
;
3611 zval
* local_TLE3
= NULL
;
3612 zval
* local_TSt24
= NULL
;
3613 zval
* local_holders
= NULL
;
3614 zval
* local_leadingColon
= NULL
;
3615 zval
* local_markers
= NULL
;
3616 zval
* local_parser
= NULL
;
3617 zval
* local_sortText
= NULL
;
3618 zval
* local_title
= NULL
;
3619 zval
* local_titleText
= NULL
;
3620 zval
* local_wgContLang
= NULL
;
3621 // Add all parameters as local variables
3623 int num_args
= ZEND_NUM_ARGS ();
3625 zend_get_parameters_array(0, num_args
, params
);
3627 params
[0]->refcount
++;
3628 if (local_parser
!= NULL
)
3630 zval_ptr_dtor (&local_parser
);
3632 local_parser
= params
[0];
3634 params
[1]->refcount
++;
3635 if (local_holders
!= NULL
)
3637 zval_ptr_dtor (&local_holders
);
3639 local_holders
= params
[1];
3641 params
[2]->refcount
++;
3642 if (local_markers
!= NULL
)
3644 zval_ptr_dtor (&local_markers
);
3646 local_markers
= params
[2];
3648 params
[3]->refcount
++;
3649 if (local_title
!= NULL
)
3651 zval_ptr_dtor (&local_title
);
3653 local_title
= params
[3];
3655 params
[4]->refcount
++;
3656 if (local_titleText
!= NULL
)
3658 zval_ptr_dtor (&local_titleText
);
3660 local_titleText
= params
[4];
3664 zval
* default_value
;
3666 zval
* local___static_value__
= NULL
;
3667 // $__static_value__ = NULL;
3669 if (local___static_value__
== NULL
)
3671 local___static_value__
= EG (uninitialized_zval_ptr
);
3672 local___static_value__
->refcount
++;
3674 zval
** p_lhs
= &local___static_value__
;
3677 if ((*p_lhs
)->is_ref
)
3679 // Always overwrite the current value
3685 ALLOC_INIT_ZVAL (value
);
3686 zval_ptr_dtor (p_lhs
);
3692 phc_check_invariants (TSRMLS_C
);
3694 default_value
= local___static_value__
;
3695 assert(!default_value
->is_ref
);
3696 default_value
->refcount
++;
3697 if (local___static_value__
!= NULL
)
3699 zval_ptr_dtor (&local___static_value__
);
3702 default_value
->refcount
--;
3703 params
[5] = default_value
;
3705 params
[5]->refcount
++;
3706 if (local_sortText
!= NULL
)
3708 zval_ptr_dtor (&local_sortText
);
3710 local_sortText
= params
[5];
3714 zval
* default_value
;
3716 zval
* local___static_value__
= NULL
;
3717 // $__static_value__ = False;
3719 if (local___static_value__
== NULL
)
3721 local___static_value__
= EG (uninitialized_zval_ptr
);
3722 local___static_value__
->refcount
++;
3724 zval
** p_lhs
= &local___static_value__
;
3727 if ((*p_lhs
)->is_ref
)
3729 // Always overwrite the current value
3735 ALLOC_INIT_ZVAL (value
);
3736 zval_ptr_dtor (p_lhs
);
3740 ZVAL_BOOL (value
, 0);
3742 phc_check_invariants (TSRMLS_C
);
3744 default_value
= local___static_value__
;
3745 assert(!default_value
->is_ref
);
3746 default_value
->refcount
++;
3747 if (local___static_value__
!= NULL
)
3749 zval_ptr_dtor (&local___static_value__
);
3752 default_value
->refcount
--;
3753 params
[6] = default_value
;
3755 params
[6]->refcount
++;
3756 if (local_leadingColon
!= NULL
)
3758 zval_ptr_dtor (&local_leadingColon
);
3760 local_leadingColon
= params
[6];
3763 // global $wgContLang;
3765 if (local_wgContLang
== NULL
)
3767 local_wgContLang
= EG (uninitialized_zval_ptr
);
3768 local_wgContLang
->refcount
++;
3770 zval
** p_local
= &local_wgContLang
;
3772 zval
** p_global
= get_st_entry (&EG(symbol_table
), "wgContLang", 10 + 1, 2660379225u TSRMLS_CC
);
3774 sep_copy_on_write (p_global
);
3775 copy_into_ref (p_local
, p_global
);
3776 phc_check_invariants (TSRMLS_C
);
3778 // if (leadingColon) goto L36 else goto L37;
3781 if (local_leadingColon
== NULL
)
3782 p_cond
= EG (uninitialized_zval_ptr
);
3784 p_cond
= local_leadingColon
;
3786 zend_bool bcond
= zend_is_true (p_cond
);
3791 phc_check_invariants (TSRMLS_C
);
3797 if (local_TLE17
== NULL
)
3799 local_TLE17
= EG (uninitialized_zval_ptr
);
3800 local_TLE17
->refcount
++;
3802 zval
** p_lhs
= &local_TLE17
;
3805 if ((*p_lhs
)->is_ref
)
3807 // Always overwrite the current value
3813 ALLOC_INIT_ZVAL (value
);
3814 zval_ptr_dtor (p_lhs
);
3818 ZVAL_BOOL (value
, 1);
3820 phc_check_invariants (TSRMLS_C
);
3825 if (local_TLE17
== NULL
)
3826 rhs
= EG (uninitialized_zval_ptr
);
3830 // Run-time return by reference has different semantics to compile-time.
3831 // If the function has CTRBR and RTRBR, the the assignment will be
3832 // reference. If one or the other is return-by-copy, the result will be
3833 // by copy. Its a question of whether its separated at return-time (which
3834 // we do here) or at the call-site.
3835 return_value
->value
= rhs
->value
;
3836 return_value
->type
= rhs
->type
;
3837 zval_copy_ctor (return_value
);
3838 goto end_of_function
;
3839 phc_check_invariants (TSRMLS_C
);
3844 phc_check_invariants (TSRMLS_C
);
3851 phc_check_invariants (TSRMLS_C
);
3855 // $TLE3 = isset($sortText);
3857 if (local_TLE3
== NULL
)
3859 local_TLE3
= EG (uninitialized_zval_ptr
);
3860 local_TLE3
->refcount
++;
3862 zval
** p_lhs
= &local_TLE3
;
3864 if ((*p_lhs
)->is_ref
)
3866 // Always overwrite the current value
3872 ALLOC_INIT_ZVAL (value
);
3873 zval_ptr_dtor (p_lhs
);
3876 ZVAL_BOOL(value
, local_sortText
!= NULL
&& !ZVAL_IS_NULL(local_sortText
));
3877 phc_check_invariants (TSRMLS_C
);
3879 // if (TLE3) goto L39 else goto L40;
3882 if (local_TLE3
== NULL
)
3883 p_cond
= EG (uninitialized_zval_ptr
);
3885 p_cond
= local_TLE3
;
3887 zend_bool bcond
= zend_is_true (p_cond
);
3892 phc_check_invariants (TSRMLS_C
);
3896 // $TEF4 = $markers->findmarker($sortText);
3898 if (local_markers
== NULL
)
3900 local_markers
= EG (uninitialized_zval_ptr
);
3901 local_markers
->refcount
++;
3903 zval
** p_obj
= &local_markers
;
3905 zend_fcall_info fci_object
;
3906 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
3907 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "findmarker", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 30 TSRMLS_CC
);
3908 zend_function
* signature
= fcic_object
.function_handler
;
3909 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
3913 // TODO: find names to replace index
3916 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
3920 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
3925 // Setup array of arguments
3926 // TODO: i think arrays of size 0 is an error
3929 zval
** args_ind
[1];
3932 destruct
[af_index
] = 0;
3933 if (by_ref
[af_index
])
3935 if (local_sortText
== NULL
)
3937 local_sortText
= EG (uninitialized_zval_ptr
);
3938 local_sortText
->refcount
++;
3940 zval
** p_arg
= &local_sortText
;
3942 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
3943 assert (!in_copy_on_write (*args_ind
[af_index
]));
3944 args
[af_index
] = *args_ind
[af_index
];
3949 if (local_sortText
== NULL
)
3950 arg
= EG (uninitialized_zval_ptr
);
3952 arg
= local_sortText
;
3954 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
3955 args_ind
[af_index
] = &args
[af_index
];
3960 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 30, NULL TSRMLS_CC
);
3962 // save existing parameters, in case of recursion
3963 int param_count_save
= fci_object
.param_count
;
3964 zval
*** params_save
= fci_object
.params
;
3965 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
3970 fci_object
.params
= args_ind
;
3971 fci_object
.param_count
= 1;
3972 fci_object
.retval_ptr_ptr
= &rhs
;
3974 // call the function
3975 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
3976 assert(success
== SUCCESS
);
3979 fci_object
.params
= params_save
;
3980 fci_object
.param_count
= param_count_save
;
3981 fci_object
.retval_ptr_ptr
= retval_save
;
3984 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
3987 for (i
= 0; i
< 1; i
++)
3991 assert (destruct
[i
]);
3992 zval_ptr_dtor (args_ind
[i
]);
3997 // When the Zend engine returns by reference, it allocates a zval into
3998 // retval_ptr_ptr. To return by reference, the callee writes into the
3999 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
4000 // not actually return anything). So the zval returned - whether we return
4001 // it, or it is the allocated zval - has a refcount of 1.
4003 // The caller is responsible for cleaning that up (note, this is unaffected
4004 // by whether it is added to some COW set).
4006 // For reasons unknown, the Zend API resets the refcount and is_ref fields
4007 // of the return value after the function returns (unless the callee is
4008 // interpreted). If the function is supposed to return by reference, this
4009 // loses the refcount. This only happens when non-interpreted code is
4010 // called. We work around it, when compiled code is called, by saving the
4011 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
4012 // that we may create an error if our code is called by a callback, and
4013 // returns by reference, and the callback returns by reference. At least
4014 // this is an obscure case.
4015 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4017 assert (rhs
!= EG(uninitialized_zval_ptr
));
4019 if (saved_refcount
!= 0)
4021 rhs
->refcount
= saved_refcount
;
4025 saved_refcount
= 0; // for 'obscure cases'
4027 if (local_TEF4
== NULL
)
4029 local_TEF4
= EG (uninitialized_zval_ptr
);
4030 local_TEF4
->refcount
++;
4032 zval
** p_lhs
= &local_TEF4
;
4034 write_var (p_lhs
, rhs
);
4037 zval_ptr_dtor (&rhs
);
4038 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4039 zval_ptr_dtor (&rhs
);
4041 phc_check_invariants (TSRMLS_C
);
4046 phc_check_invariants (TSRMLS_C
);
4052 if (local_TEF4
== NULL
)
4054 local_TEF4
= EG (uninitialized_zval_ptr
);
4055 local_TEF4
->refcount
++;
4057 zval
** p_lhs
= &local_TEF4
;
4060 if (local_TLE3
== NULL
)
4061 rhs
= EG (uninitialized_zval_ptr
);
4067 if ((*p_lhs
)->is_ref
)
4068 overwrite_lhs (*p_lhs
, rhs
);
4071 zval_ptr_dtor (p_lhs
);
4074 // Take a copy of RHS for LHS
4075 *p_lhs
= zvp_clone_ex (rhs
);
4087 phc_check_invariants (TSRMLS_C
);
4092 phc_check_invariants (TSRMLS_C
);
4096 // $TLE18 = (bool) $TEF4;
4098 if (local_TLE18
== NULL
)
4100 local_TLE18
= EG (uninitialized_zval_ptr
);
4101 local_TLE18
->refcount
++;
4103 zval
** p_lhs
= &local_TLE18
;
4106 if (local_TEF4
== NULL
)
4107 rhs
= EG (uninitialized_zval_ptr
);
4113 if ((*p_lhs
)->is_ref
)
4114 overwrite_lhs (*p_lhs
, rhs
);
4117 zval_ptr_dtor (p_lhs
);
4120 // Take a copy of RHS for LHS
4121 *p_lhs
= zvp_clone_ex (rhs
);
4134 assert (IS_BOOL
>= 0 && IS_BOOL
<= 6);
4135 if ((*p_lhs
)->type
!= IS_BOOL
)
4137 sep_copy_on_write (p_lhs
);
4138 convert_to_boolean (*p_lhs
);
4141 phc_check_invariants (TSRMLS_C
);
4143 // if (TLE18) goto L42 else goto L43;
4146 if (local_TLE18
== NULL
)
4147 p_cond
= EG (uninitialized_zval_ptr
);
4149 p_cond
= local_TLE18
;
4151 zend_bool bcond
= zend_is_true (p_cond
);
4156 phc_check_invariants (TSRMLS_C
);
4160 // $sortText = $markers->expand($sortText);
4162 if (local_markers
== NULL
)
4164 local_markers
= EG (uninitialized_zval_ptr
);
4165 local_markers
->refcount
++;
4167 zval
** p_obj
= &local_markers
;
4169 zend_fcall_info fci_object
;
4170 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
4171 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "expand", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 34 TSRMLS_CC
);
4172 zend_function
* signature
= fcic_object
.function_handler
;
4173 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
4177 // TODO: find names to replace index
4180 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
4184 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
4189 // Setup array of arguments
4190 // TODO: i think arrays of size 0 is an error
4193 zval
** args_ind
[1];
4196 destruct
[af_index
] = 0;
4197 if (by_ref
[af_index
])
4199 if (local_sortText
== NULL
)
4201 local_sortText
= EG (uninitialized_zval_ptr
);
4202 local_sortText
->refcount
++;
4204 zval
** p_arg
= &local_sortText
;
4206 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
4207 assert (!in_copy_on_write (*args_ind
[af_index
]));
4208 args
[af_index
] = *args_ind
[af_index
];
4213 if (local_sortText
== NULL
)
4214 arg
= EG (uninitialized_zval_ptr
);
4216 arg
= local_sortText
;
4218 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
4219 args_ind
[af_index
] = &args
[af_index
];
4224 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 34, NULL TSRMLS_CC
);
4226 // save existing parameters, in case of recursion
4227 int param_count_save
= fci_object
.param_count
;
4228 zval
*** params_save
= fci_object
.params
;
4229 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
4234 fci_object
.params
= args_ind
;
4235 fci_object
.param_count
= 1;
4236 fci_object
.retval_ptr_ptr
= &rhs
;
4238 // call the function
4239 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
4240 assert(success
== SUCCESS
);
4243 fci_object
.params
= params_save
;
4244 fci_object
.param_count
= param_count_save
;
4245 fci_object
.retval_ptr_ptr
= retval_save
;
4248 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
4251 for (i
= 0; i
< 1; i
++)
4255 assert (destruct
[i
]);
4256 zval_ptr_dtor (args_ind
[i
]);
4261 // When the Zend engine returns by reference, it allocates a zval into
4262 // retval_ptr_ptr. To return by reference, the callee writes into the
4263 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
4264 // not actually return anything). So the zval returned - whether we return
4265 // it, or it is the allocated zval - has a refcount of 1.
4267 // The caller is responsible for cleaning that up (note, this is unaffected
4268 // by whether it is added to some COW set).
4270 // For reasons unknown, the Zend API resets the refcount and is_ref fields
4271 // of the return value after the function returns (unless the callee is
4272 // interpreted). If the function is supposed to return by reference, this
4273 // loses the refcount. This only happens when non-interpreted code is
4274 // called. We work around it, when compiled code is called, by saving the
4275 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
4276 // that we may create an error if our code is called by a callback, and
4277 // returns by reference, and the callback returns by reference. At least
4278 // this is an obscure case.
4279 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4281 assert (rhs
!= EG(uninitialized_zval_ptr
));
4283 if (saved_refcount
!= 0)
4285 rhs
->refcount
= saved_refcount
;
4289 saved_refcount
= 0; // for 'obscure cases'
4291 if (local_sortText
== NULL
)
4293 local_sortText
= EG (uninitialized_zval_ptr
);
4294 local_sortText
->refcount
++;
4296 zval
** p_lhs
= &local_sortText
;
4298 write_var (p_lhs
, rhs
);
4301 zval_ptr_dtor (&rhs
);
4302 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4303 zval_ptr_dtor (&rhs
);
4305 phc_check_invariants (TSRMLS_C
);
4309 if (local_TLE19
== NULL
)
4311 local_TLE19
= EG (uninitialized_zval_ptr
);
4312 local_TLE19
->refcount
++;
4314 zval
** p_lhs
= &local_TLE19
;
4317 if ((*p_lhs
)->is_ref
)
4319 // Always overwrite the current value
4325 ALLOC_INIT_ZVAL (value
);
4326 zval_ptr_dtor (p_lhs
);
4330 ZVAL_BOOL (value
, 0);
4332 phc_check_invariants (TSRMLS_C
);
4337 if (local_TLE19
== NULL
)
4338 rhs
= EG (uninitialized_zval_ptr
);
4342 // Run-time return by reference has different semantics to compile-time.
4343 // If the function has CTRBR and RTRBR, the the assignment will be
4344 // reference. If one or the other is return-by-copy, the result will be
4345 // by copy. Its a question of whether its separated at return-time (which
4346 // we do here) or at the call-site.
4347 return_value
->value
= rhs
->value
;
4348 return_value
->type
= rhs
->type
;
4349 zval_copy_ctor (return_value
);
4350 goto end_of_function
;
4351 phc_check_invariants (TSRMLS_C
);
4356 phc_check_invariants (TSRMLS_C
);
4363 phc_check_invariants (TSRMLS_C
);
4367 // $TLE20 = isset($sortText);
4369 if (local_TLE20
== NULL
)
4371 local_TLE20
= EG (uninitialized_zval_ptr
);
4372 local_TLE20
->refcount
++;
4374 zval
** p_lhs
= &local_TLE20
;
4376 if ((*p_lhs
)->is_ref
)
4378 // Always overwrite the current value
4384 ALLOC_INIT_ZVAL (value
);
4385 zval_ptr_dtor (p_lhs
);
4388 ZVAL_BOOL(value
, local_sortText
!= NULL
&& !ZVAL_IS_NULL(local_sortText
));
4389 phc_check_invariants (TSRMLS_C
);
4391 // $TLE21 = !$TLE20;
4393 if (local_TLE21
== NULL
)
4395 local_TLE21
= EG (uninitialized_zval_ptr
);
4396 local_TLE21
->refcount
++;
4398 zval
** p_lhs
= &local_TLE21
;
4401 if (local_TLE20
== NULL
)
4402 rhs
= EG (uninitialized_zval_ptr
);
4406 if (in_copy_on_write (*p_lhs
))
4408 zval_ptr_dtor (p_lhs
);
4409 ALLOC_INIT_ZVAL (*p_lhs
);
4413 int result_is_operand
= (*p_lhs
== rhs
);
4414 boolean_not_function (*p_lhs
, rhs TSRMLS_CC
);
4415 if (!result_is_operand
)
4417 phc_check_invariants (TSRMLS_C
);
4419 // if (TLE21) goto L45 else goto L46;
4422 if (local_TLE21
== NULL
)
4423 p_cond
= EG (uninitialized_zval_ptr
);
4425 p_cond
= local_TLE21
;
4427 zend_bool bcond
= zend_is_true (p_cond
);
4432 phc_check_invariants (TSRMLS_C
);
4436 // $sortText = $parser->getdefaultsort();
4438 if (local_parser
== NULL
)
4440 local_parser
= EG (uninitialized_zval_ptr
);
4441 local_parser
->refcount
++;
4443 zval
** p_obj
= &local_parser
;
4445 zend_fcall_info fci_object
;
4446 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
4447 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "getdefaultsort", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 38 TSRMLS_CC
);
4448 zend_function
* signature
= fcic_object
.function_handler
;
4449 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
4455 // Setup array of arguments
4456 // TODO: i think arrays of size 0 is an error
4459 zval
** args_ind
[0];
4464 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 38, NULL TSRMLS_CC
);
4466 // save existing parameters, in case of recursion
4467 int param_count_save
= fci_object
.param_count
;
4468 zval
*** params_save
= fci_object
.params
;
4469 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
4474 fci_object
.params
= args_ind
;
4475 fci_object
.param_count
= 0;
4476 fci_object
.retval_ptr_ptr
= &rhs
;
4478 // call the function
4479 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
4480 assert(success
== SUCCESS
);
4483 fci_object
.params
= params_save
;
4484 fci_object
.param_count
= param_count_save
;
4485 fci_object
.retval_ptr_ptr
= retval_save
;
4488 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
4491 for (i
= 0; i
< 0; i
++)
4495 assert (destruct
[i
]);
4496 zval_ptr_dtor (args_ind
[i
]);
4501 // When the Zend engine returns by reference, it allocates a zval into
4502 // retval_ptr_ptr. To return by reference, the callee writes into the
4503 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
4504 // not actually return anything). So the zval returned - whether we return
4505 // it, or it is the allocated zval - has a refcount of 1.
4507 // The caller is responsible for cleaning that up (note, this is unaffected
4508 // by whether it is added to some COW set).
4510 // For reasons unknown, the Zend API resets the refcount and is_ref fields
4511 // of the return value after the function returns (unless the callee is
4512 // interpreted). If the function is supposed to return by reference, this
4513 // loses the refcount. This only happens when non-interpreted code is
4514 // called. We work around it, when compiled code is called, by saving the
4515 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
4516 // that we may create an error if our code is called by a callback, and
4517 // returns by reference, and the callback returns by reference. At least
4518 // this is an obscure case.
4519 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4521 assert (rhs
!= EG(uninitialized_zval_ptr
));
4523 if (saved_refcount
!= 0)
4525 rhs
->refcount
= saved_refcount
;
4529 saved_refcount
= 0; // for 'obscure cases'
4531 if (local_sortText
== NULL
)
4533 local_sortText
= EG (uninitialized_zval_ptr
);
4534 local_sortText
->refcount
++;
4536 zval
** p_lhs
= &local_sortText
;
4538 write_var (p_lhs
, rhs
);
4541 zval_ptr_dtor (&rhs
);
4542 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4543 zval_ptr_dtor (&rhs
);
4545 phc_check_invariants (TSRMLS_C
);
4550 phc_check_invariants (TSRMLS_C
);
4557 phc_check_invariants (TSRMLS_C
);
4561 // $sortText = sanitizer::decodecharreferences($sortText);
4563 initialize_function_call (&sanitizer_decodecharreferences_fci
, &sanitizer_decodecharreferences_fcic
, "sanitizer::decodecharreferences", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 39 TSRMLS_CC
);
4564 zend_function
* signature
= sanitizer_decodecharreferences_fcic
.function_handler
;
4565 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
4569 // TODO: find names to replace index
4572 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
4576 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
4581 // Setup array of arguments
4582 // TODO: i think arrays of size 0 is an error
4585 zval
** args_ind
[1];
4588 destruct
[af_index
] = 0;
4589 if (by_ref
[af_index
])
4591 if (local_sortText
== NULL
)
4593 local_sortText
= EG (uninitialized_zval_ptr
);
4594 local_sortText
->refcount
++;
4596 zval
** p_arg
= &local_sortText
;
4598 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
4599 assert (!in_copy_on_write (*args_ind
[af_index
]));
4600 args
[af_index
] = *args_ind
[af_index
];
4605 if (local_sortText
== NULL
)
4606 arg
= EG (uninitialized_zval_ptr
);
4608 arg
= local_sortText
;
4610 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
4611 args_ind
[af_index
] = &args
[af_index
];
4616 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 39, NULL TSRMLS_CC
);
4618 // save existing parameters, in case of recursion
4619 int param_count_save
= sanitizer_decodecharreferences_fci
.param_count
;
4620 zval
*** params_save
= sanitizer_decodecharreferences_fci
.params
;
4621 zval
** retval_save
= sanitizer_decodecharreferences_fci
.retval_ptr_ptr
;
4626 sanitizer_decodecharreferences_fci
.params
= args_ind
;
4627 sanitizer_decodecharreferences_fci
.param_count
= 1;
4628 sanitizer_decodecharreferences_fci
.retval_ptr_ptr
= &rhs
;
4630 // call the function
4631 int success
= zend_call_function (&sanitizer_decodecharreferences_fci
, &sanitizer_decodecharreferences_fcic TSRMLS_CC
);
4632 assert(success
== SUCCESS
);
4635 sanitizer_decodecharreferences_fci
.params
= params_save
;
4636 sanitizer_decodecharreferences_fci
.param_count
= param_count_save
;
4637 sanitizer_decodecharreferences_fci
.retval_ptr_ptr
= retval_save
;
4640 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
4643 for (i
= 0; i
< 1; i
++)
4647 assert (destruct
[i
]);
4648 zval_ptr_dtor (args_ind
[i
]);
4653 // When the Zend engine returns by reference, it allocates a zval into
4654 // retval_ptr_ptr. To return by reference, the callee writes into the
4655 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
4656 // not actually return anything). So the zval returned - whether we return
4657 // it, or it is the allocated zval - has a refcount of 1.
4659 // The caller is responsible for cleaning that up (note, this is unaffected
4660 // by whether it is added to some COW set).
4662 // For reasons unknown, the Zend API resets the refcount and is_ref fields
4663 // of the return value after the function returns (unless the callee is
4664 // interpreted). If the function is supposed to return by reference, this
4665 // loses the refcount. This only happens when non-interpreted code is
4666 // called. We work around it, when compiled code is called, by saving the
4667 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
4668 // that we may create an error if our code is called by a callback, and
4669 // returns by reference, and the callback returns by reference. At least
4670 // this is an obscure case.
4671 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4673 assert (rhs
!= EG(uninitialized_zval_ptr
));
4675 if (saved_refcount
!= 0)
4677 rhs
->refcount
= saved_refcount
;
4681 saved_refcount
= 0; // for 'obscure cases'
4683 if (local_sortText
== NULL
)
4685 local_sortText
= EG (uninitialized_zval_ptr
);
4686 local_sortText
->refcount
++;
4688 zval
** p_lhs
= &local_sortText
;
4690 write_var (p_lhs
, rhs
);
4693 zval_ptr_dtor (&rhs
);
4694 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4695 zval_ptr_dtor (&rhs
);
4697 phc_check_invariants (TSRMLS_C
);
4702 if (local_TLE22
== NULL
)
4704 local_TLE22
= EG (uninitialized_zval_ptr
);
4705 local_TLE22
->refcount
++;
4707 zval
** p_lhs
= &local_TLE22
;
4710 if ((*p_lhs
)->is_ref
)
4712 // Always overwrite the current value
4718 ALLOC_INIT_ZVAL (value
);
4719 zval_ptr_dtor (p_lhs
);
4723 ZVAL_STRINGL(value
, "\012", 1, 1);
4725 phc_check_invariants (TSRMLS_C
);
4729 if (local_TLE23
== NULL
)
4731 local_TLE23
= EG (uninitialized_zval_ptr
);
4732 local_TLE23
->refcount
++;
4734 zval
** p_lhs
= &local_TLE23
;
4737 if ((*p_lhs
)->is_ref
)
4739 // Always overwrite the current value
4745 ALLOC_INIT_ZVAL (value
);
4746 zval_ptr_dtor (p_lhs
);
4750 ZVAL_STRINGL(value
, "", 0, 1);
4752 phc_check_invariants (TSRMLS_C
);
4754 // $sortText = str_replace($TLE22, $TLE23, $sortText);
4756 initialize_function_call (&str_replace_fci
, &str_replace_fcic
, "str_replace", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 40 TSRMLS_CC
);
4757 zend_function
* signature
= str_replace_fcic
.function_handler
;
4758 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
4762 // TODO: find names to replace index
4765 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
4769 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
4772 // TODO: find names to replace index
4775 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
4779 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
4782 // TODO: find names to replace index
4785 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
4789 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
4794 // Setup array of arguments
4795 // TODO: i think arrays of size 0 is an error
4798 zval
** args_ind
[3];
4801 destruct
[af_index
] = 0;
4802 if (by_ref
[af_index
])
4804 if (local_TLE22
== NULL
)
4806 local_TLE22
= EG (uninitialized_zval_ptr
);
4807 local_TLE22
->refcount
++;
4809 zval
** p_arg
= &local_TLE22
;
4811 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
4812 assert (!in_copy_on_write (*args_ind
[af_index
]));
4813 args
[af_index
] = *args_ind
[af_index
];
4818 if (local_TLE22
== NULL
)
4819 arg
= EG (uninitialized_zval_ptr
);
4823 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
4824 args_ind
[af_index
] = &args
[af_index
];
4827 destruct
[af_index
] = 0;
4828 if (by_ref
[af_index
])
4830 if (local_TLE23
== NULL
)
4832 local_TLE23
= EG (uninitialized_zval_ptr
);
4833 local_TLE23
->refcount
++;
4835 zval
** p_arg
= &local_TLE23
;
4837 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
4838 assert (!in_copy_on_write (*args_ind
[af_index
]));
4839 args
[af_index
] = *args_ind
[af_index
];
4844 if (local_TLE23
== NULL
)
4845 arg
= EG (uninitialized_zval_ptr
);
4849 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
4850 args_ind
[af_index
] = &args
[af_index
];
4853 destruct
[af_index
] = 0;
4854 if (by_ref
[af_index
])
4856 if (local_sortText
== NULL
)
4858 local_sortText
= EG (uninitialized_zval_ptr
);
4859 local_sortText
->refcount
++;
4861 zval
** p_arg
= &local_sortText
;
4863 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
4864 assert (!in_copy_on_write (*args_ind
[af_index
]));
4865 args
[af_index
] = *args_ind
[af_index
];
4870 if (local_sortText
== NULL
)
4871 arg
= EG (uninitialized_zval_ptr
);
4873 arg
= local_sortText
;
4875 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
4876 args_ind
[af_index
] = &args
[af_index
];
4881 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 40, NULL TSRMLS_CC
);
4883 // save existing parameters, in case of recursion
4884 int param_count_save
= str_replace_fci
.param_count
;
4885 zval
*** params_save
= str_replace_fci
.params
;
4886 zval
** retval_save
= str_replace_fci
.retval_ptr_ptr
;
4891 str_replace_fci
.params
= args_ind
;
4892 str_replace_fci
.param_count
= 3;
4893 str_replace_fci
.retval_ptr_ptr
= &rhs
;
4895 // call the function
4896 int success
= zend_call_function (&str_replace_fci
, &str_replace_fcic TSRMLS_CC
);
4897 assert(success
== SUCCESS
);
4900 str_replace_fci
.params
= params_save
;
4901 str_replace_fci
.param_count
= param_count_save
;
4902 str_replace_fci
.retval_ptr_ptr
= retval_save
;
4905 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
4908 for (i
= 0; i
< 3; i
++)
4912 assert (destruct
[i
]);
4913 zval_ptr_dtor (args_ind
[i
]);
4918 // When the Zend engine returns by reference, it allocates a zval into
4919 // retval_ptr_ptr. To return by reference, the callee writes into the
4920 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
4921 // not actually return anything). So the zval returned - whether we return
4922 // it, or it is the allocated zval - has a refcount of 1.
4924 // The caller is responsible for cleaning that up (note, this is unaffected
4925 // by whether it is added to some COW set).
4927 // For reasons unknown, the Zend API resets the refcount and is_ref fields
4928 // of the return value after the function returns (unless the callee is
4929 // interpreted). If the function is supposed to return by reference, this
4930 // loses the refcount. This only happens when non-interpreted code is
4931 // called. We work around it, when compiled code is called, by saving the
4932 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
4933 // that we may create an error if our code is called by a callback, and
4934 // returns by reference, and the callback returns by reference. At least
4935 // this is an obscure case.
4936 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4938 assert (rhs
!= EG(uninitialized_zval_ptr
));
4940 if (saved_refcount
!= 0)
4942 rhs
->refcount
= saved_refcount
;
4946 saved_refcount
= 0; // for 'obscure cases'
4948 if (local_sortText
== NULL
)
4950 local_sortText
= EG (uninitialized_zval_ptr
);
4951 local_sortText
->refcount
++;
4953 zval
** p_lhs
= &local_sortText
;
4955 write_var (p_lhs
, rhs
);
4958 zval_ptr_dtor (&rhs
);
4959 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
4960 zval_ptr_dtor (&rhs
);
4962 phc_check_invariants (TSRMLS_C
);
4964 // $sortText = $wgContLang->convertcategorykey($sortText);
4966 if (local_wgContLang
== NULL
)
4968 local_wgContLang
= EG (uninitialized_zval_ptr
);
4969 local_wgContLang
->refcount
++;
4971 zval
** p_obj
= &local_wgContLang
;
4973 zend_fcall_info fci_object
;
4974 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
4975 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "convertcategorykey", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 41 TSRMLS_CC
);
4976 zend_function
* signature
= fcic_object
.function_handler
;
4977 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
4981 // TODO: find names to replace index
4984 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
4988 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
4993 // Setup array of arguments
4994 // TODO: i think arrays of size 0 is an error
4997 zval
** args_ind
[1];
5000 destruct
[af_index
] = 0;
5001 if (by_ref
[af_index
])
5003 if (local_sortText
== NULL
)
5005 local_sortText
= EG (uninitialized_zval_ptr
);
5006 local_sortText
->refcount
++;
5008 zval
** p_arg
= &local_sortText
;
5010 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
5011 assert (!in_copy_on_write (*args_ind
[af_index
]));
5012 args
[af_index
] = *args_ind
[af_index
];
5017 if (local_sortText
== NULL
)
5018 arg
= EG (uninitialized_zval_ptr
);
5020 arg
= local_sortText
;
5022 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
5023 args_ind
[af_index
] = &args
[af_index
];
5028 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 41, NULL TSRMLS_CC
);
5030 // save existing parameters, in case of recursion
5031 int param_count_save
= fci_object
.param_count
;
5032 zval
*** params_save
= fci_object
.params
;
5033 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
5038 fci_object
.params
= args_ind
;
5039 fci_object
.param_count
= 1;
5040 fci_object
.retval_ptr_ptr
= &rhs
;
5042 // call the function
5043 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
5044 assert(success
== SUCCESS
);
5047 fci_object
.params
= params_save
;
5048 fci_object
.param_count
= param_count_save
;
5049 fci_object
.retval_ptr_ptr
= retval_save
;
5052 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
5055 for (i
= 0; i
< 1; i
++)
5059 assert (destruct
[i
]);
5060 zval_ptr_dtor (args_ind
[i
]);
5065 // When the Zend engine returns by reference, it allocates a zval into
5066 // retval_ptr_ptr. To return by reference, the callee writes into the
5067 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
5068 // not actually return anything). So the zval returned - whether we return
5069 // it, or it is the allocated zval - has a refcount of 1.
5071 // The caller is responsible for cleaning that up (note, this is unaffected
5072 // by whether it is added to some COW set).
5074 // For reasons unknown, the Zend API resets the refcount and is_ref fields
5075 // of the return value after the function returns (unless the callee is
5076 // interpreted). If the function is supposed to return by reference, this
5077 // loses the refcount. This only happens when non-interpreted code is
5078 // called. We work around it, when compiled code is called, by saving the
5079 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
5080 // that we may create an error if our code is called by a callback, and
5081 // returns by reference, and the callback returns by reference. At least
5082 // this is an obscure case.
5083 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
5085 assert (rhs
!= EG(uninitialized_zval_ptr
));
5087 if (saved_refcount
!= 0)
5089 rhs
->refcount
= saved_refcount
;
5093 saved_refcount
= 0; // for 'obscure cases'
5095 if (local_sortText
== NULL
)
5097 local_sortText
= EG (uninitialized_zval_ptr
);
5098 local_sortText
->refcount
++;
5100 zval
** p_lhs
= &local_sortText
;
5102 write_var (p_lhs
, rhs
);
5105 zval_ptr_dtor (&rhs
);
5106 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
5107 zval_ptr_dtor (&rhs
);
5109 phc_check_invariants (TSRMLS_C
);
5111 // $TSt24 = $parser->mOutput;
5113 if (local_parser
== NULL
)
5115 local_parser
= EG (uninitialized_zval_ptr
);
5116 local_parser
->refcount
++;
5118 zval
** p_obj
= &local_parser
;
5121 INIT_ZVAL (field_name
);
5122 ZVAL_STRING (&field_name
, "mOutput", 0);
5124 // I *think* this is correct, but documentation of the Zend API is scarce :)
5125 zval
* field
= Z_OBJ_HT_PP(p_obj
)->read_property(*p_obj
, &field_name
, BP_VAR_R TSRMLS_CC
);
5126 if (local_TSt24
== NULL
)
5128 local_TSt24
= EG (uninitialized_zval_ptr
);
5129 local_TSt24
->refcount
++;
5131 zval
** p_lhs
= &local_TSt24
;
5133 write_var (p_lhs
, field
);
5134 phc_check_invariants (TSRMLS_C
);
5136 // $TLE25 = $title->getdbkey();
5138 if (local_title
== NULL
)
5140 local_title
= EG (uninitialized_zval_ptr
);
5141 local_title
->refcount
++;
5143 zval
** p_obj
= &local_title
;
5145 zend_fcall_info fci_object
;
5146 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
5147 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "getdbkey", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 42 TSRMLS_CC
);
5148 zend_function
* signature
= fcic_object
.function_handler
;
5149 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
5155 // Setup array of arguments
5156 // TODO: i think arrays of size 0 is an error
5159 zval
** args_ind
[0];
5164 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 42, NULL TSRMLS_CC
);
5166 // save existing parameters, in case of recursion
5167 int param_count_save
= fci_object
.param_count
;
5168 zval
*** params_save
= fci_object
.params
;
5169 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
5174 fci_object
.params
= args_ind
;
5175 fci_object
.param_count
= 0;
5176 fci_object
.retval_ptr_ptr
= &rhs
;
5178 // call the function
5179 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
5180 assert(success
== SUCCESS
);
5183 fci_object
.params
= params_save
;
5184 fci_object
.param_count
= param_count_save
;
5185 fci_object
.retval_ptr_ptr
= retval_save
;
5188 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
5191 for (i
= 0; i
< 0; i
++)
5195 assert (destruct
[i
]);
5196 zval_ptr_dtor (args_ind
[i
]);
5201 // When the Zend engine returns by reference, it allocates a zval into
5202 // retval_ptr_ptr. To return by reference, the callee writes into the
5203 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
5204 // not actually return anything). So the zval returned - whether we return
5205 // it, or it is the allocated zval - has a refcount of 1.
5207 // The caller is responsible for cleaning that up (note, this is unaffected
5208 // by whether it is added to some COW set).
5210 // For reasons unknown, the Zend API resets the refcount and is_ref fields
5211 // of the return value after the function returns (unless the callee is
5212 // interpreted). If the function is supposed to return by reference, this
5213 // loses the refcount. This only happens when non-interpreted code is
5214 // called. We work around it, when compiled code is called, by saving the
5215 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
5216 // that we may create an error if our code is called by a callback, and
5217 // returns by reference, and the callback returns by reference. At least
5218 // this is an obscure case.
5219 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
5221 assert (rhs
!= EG(uninitialized_zval_ptr
));
5223 if (saved_refcount
!= 0)
5225 rhs
->refcount
= saved_refcount
;
5229 saved_refcount
= 0; // for 'obscure cases'
5231 if (local_TLE25
== NULL
)
5233 local_TLE25
= EG (uninitialized_zval_ptr
);
5234 local_TLE25
->refcount
++;
5236 zval
** p_lhs
= &local_TLE25
;
5238 write_var (p_lhs
, rhs
);
5241 zval_ptr_dtor (&rhs
);
5242 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
5243 zval_ptr_dtor (&rhs
);
5245 phc_check_invariants (TSRMLS_C
);
5247 // $TSt24->addcategory($TLE25, $sortText);
5249 if (local_TSt24
== NULL
)
5251 local_TSt24
= EG (uninitialized_zval_ptr
);
5252 local_TSt24
->refcount
++;
5254 zval
** p_obj
= &local_TSt24
;
5256 zend_fcall_info fci_object
;
5257 zend_fcall_info_cache fcic_object
= {0, NULL
, NULL
, NULL
};
5258 initialize_method_call (&fci_object
, &fcic_object
, p_obj
, "addcategory", "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 42 TSRMLS_CC
);
5259 zend_function
* signature
= fcic_object
.function_handler
;
5260 zend_arg_info
* arg_info
= signature
->common
.arg_info
; // optional
5264 // TODO: find names to replace index
5267 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
5271 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
5274 // TODO: find names to replace index
5277 by_ref
[abr_index
] = arg_info
->pass_by_reference
;
5281 by_ref
[abr_index
] = signature
->common
.pass_rest_by_reference
;
5286 // Setup array of arguments
5287 // TODO: i think arrays of size 0 is an error
5290 zval
** args_ind
[2];
5293 destruct
[af_index
] = 0;
5294 if (by_ref
[af_index
])
5296 if (local_TLE25
== NULL
)
5298 local_TLE25
= EG (uninitialized_zval_ptr
);
5299 local_TLE25
->refcount
++;
5301 zval
** p_arg
= &local_TLE25
;
5303 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
5304 assert (!in_copy_on_write (*args_ind
[af_index
]));
5305 args
[af_index
] = *args_ind
[af_index
];
5310 if (local_TLE25
== NULL
)
5311 arg
= EG (uninitialized_zval_ptr
);
5315 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
5316 args_ind
[af_index
] = &args
[af_index
];
5319 destruct
[af_index
] = 0;
5320 if (by_ref
[af_index
])
5322 if (local_sortText
== NULL
)
5324 local_sortText
= EG (uninitialized_zval_ptr
);
5325 local_sortText
->refcount
++;
5327 zval
** p_arg
= &local_sortText
;
5329 args_ind
[af_index
] = fetch_var_arg_by_ref (p_arg
);
5330 assert (!in_copy_on_write (*args_ind
[af_index
]));
5331 args
[af_index
] = *args_ind
[af_index
];
5336 if (local_sortText
== NULL
)
5337 arg
= EG (uninitialized_zval_ptr
);
5339 arg
= local_sortText
;
5341 args
[af_index
] = fetch_var_arg (arg
, &destruct
[af_index
]);
5342 args_ind
[af_index
] = &args
[af_index
];
5347 phc_setup_error (1, "/home/mdupont/2009/02/introspector/rdfintrospector/mediawiki/trunk/phase3/includes/parser/CoreLinkFunctions.php", 42, NULL TSRMLS_CC
);
5349 // save existing parameters, in case of recursion
5350 int param_count_save
= fci_object
.param_count
;
5351 zval
*** params_save
= fci_object
.params
;
5352 zval
** retval_save
= fci_object
.retval_ptr_ptr
;
5357 fci_object
.params
= args_ind
;
5358 fci_object
.param_count
= 2;
5359 fci_object
.retval_ptr_ptr
= &rhs
;
5361 // call the function
5362 int success
= zend_call_function (&fci_object
, &fcic_object TSRMLS_CC
);
5363 assert(success
== SUCCESS
);
5366 fci_object
.params
= params_save
;
5367 fci_object
.param_count
= param_count_save
;
5368 fci_object
.retval_ptr_ptr
= retval_save
;
5371 phc_setup_error (0, NULL
, 0, NULL TSRMLS_CC
);
5374 for (i
= 0; i
< 2; i
++)
5378 assert (destruct
[i
]);
5379 zval_ptr_dtor (args_ind
[i
]);
5384 // When the Zend engine returns by reference, it allocates a zval into
5385 // retval_ptr_ptr. To return by reference, the callee writes into the
5386 // retval_ptr_ptr, freeing the allocated value as it does. (Note, it may
5387 // not actually return anything). So the zval returned - whether we return
5388 // it, or it is the allocated zval - has a refcount of 1.
5390 // The caller is responsible for cleaning that up (note, this is unaffected
5391 // by whether it is added to some COW set).
5393 // For reasons unknown, the Zend API resets the refcount and is_ref fields
5394 // of the return value after the function returns (unless the callee is
5395 // interpreted). If the function is supposed to return by reference, this
5396 // loses the refcount. This only happens when non-interpreted code is
5397 // called. We work around it, when compiled code is called, by saving the
5398 // refcount into SAVED_REFCOUNT, in the return statement. The downside is
5399 // that we may create an error if our code is called by a callback, and
5400 // returns by reference, and the callback returns by reference. At least
5401 // this is an obscure case.
5402 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
5404 assert (rhs
!= EG(uninitialized_zval_ptr
));
5406 if (saved_refcount
!= 0)
5408 rhs
->refcount
= saved_refcount
;
5412 saved_refcount
= 0; // for 'obscure cases'
5416 zval_ptr_dtor (&rhs
);
5417 if(signature
->common
.return_reference
&& signature
->type
!= ZEND_USER_FUNCTION
)
5418 zval_ptr_dtor (&rhs
);
5420 phc_check_invariants (TSRMLS_C
);
5424 if (local_TLE26
== NULL
)
5426 local_TLE26
= EG (uninitialized_zval_ptr
);
5427 local_TLE26
->refcount
++;
5429 zval
** p_lhs
= &local_TLE26
;
5432 if ((*p_lhs
)->is_ref
)
5434 // Always overwrite the current value
5440 ALLOC_INIT_ZVAL (value
);
5441 zval_ptr_dtor (p_lhs
);
5445 ZVAL_STRINGL(value
, "", 0, 1);
5447 phc_check_invariants (TSRMLS_C
);
5452 if (local_TLE26
== NULL
)
5453 rhs
= EG (uninitialized_zval_ptr
);
5457 // Run-time return by reference has different semantics to compile-time.
5458 // If the function has CTRBR and RTRBR, the the assignment will be
5459 // reference. If one or the other is return-by-copy, the result will be
5460 // by copy. Its a question of whether its separated at return-time (which
5461 // we do here) or at the call-site.
5462 return_value
->value
= rhs
->value
;
5463 return_value
->type
= rhs
->type
;
5464 zval_copy_ctor (return_value
);
5465 goto end_of_function
;
5466 phc_check_invariants (TSRMLS_C
);
5469 end_of_function
:__attribute__((unused
));
5470 if (local_TEF4
!= NULL
)
5472 zval_ptr_dtor (&local_TEF4
);
5474 if (local_TLE17
!= NULL
)
5476 zval_ptr_dtor (&local_TLE17
);
5478 if (local_TLE18
!= NULL
)
5480 zval_ptr_dtor (&local_TLE18
);
5482 if (local_TLE19
!= NULL
)
5484 zval_ptr_dtor (&local_TLE19
);
5486 if (local_TLE20
!= NULL
)
5488 zval_ptr_dtor (&local_TLE20
);
5490 if (local_TLE21
!= NULL
)
5492 zval_ptr_dtor (&local_TLE21
);
5494 if (local_TLE22
!= NULL
)
5496 zval_ptr_dtor (&local_TLE22
);
5498 if (local_TLE23
!= NULL
)
5500 zval_ptr_dtor (&local_TLE23
);
5502 if (local_TLE25
!= NULL
)
5504 zval_ptr_dtor (&local_TLE25
);
5506 if (local_TLE26
!= NULL
)
5508 zval_ptr_dtor (&local_TLE26
);
5510 if (local_TLE3
!= NULL
)
5512 zval_ptr_dtor (&local_TLE3
);
5514 if (local_TSt24
!= NULL
)
5516 zval_ptr_dtor (&local_TSt24
);
5518 if (local_holders
!= NULL
)
5520 zval_ptr_dtor (&local_holders
);
5522 if (local_leadingColon
!= NULL
)
5524 zval_ptr_dtor (&local_leadingColon
);
5526 if (local_markers
!= NULL
)
5528 zval_ptr_dtor (&local_markers
);
5530 if (local_parser
!= NULL
)
5532 zval_ptr_dtor (&local_parser
);
5534 if (local_sortText
!= NULL
)
5536 zval_ptr_dtor (&local_sortText
);
5538 if (local_title
!= NULL
)
5540 zval_ptr_dtor (&local_title
);
5542 if (local_titleText
!= NULL
)
5544 zval_ptr_dtor (&local_titleText
);
5546 if (local_wgContLang
!= NULL
)
5548 zval_ptr_dtor (&local_wgContLang
);
5551 // ArgInfo structures (necessary to support compile time pass-by-reference)
5552 ZEND_BEGIN_ARG_INFO_EX(CoreLinkFunctions_register_arg_info
, 0, 0, 0)
5553 ZEND_ARG_INFO(0, "parser")
5556 ZEND_BEGIN_ARG_INFO_EX(CoreLinkFunctions_defaultlinkhook_arg_info
, 0, 0, 0)
5557 ZEND_ARG_INFO(0, "parser")
5558 ZEND_ARG_INFO(0, "holders")
5559 ZEND_ARG_INFO(0, "markers")
5560 ZEND_ARG_INFO(0, "title")
5561 ZEND_ARG_INFO(0, "titleText")
5562 ZEND_ARG_INFO(1, "displayText")
5563 ZEND_ARG_INFO(1, "leadingColon")
5566 ZEND_BEGIN_ARG_INFO_EX(CoreLinkFunctions_categorylinkhook_arg_info
, 0, 0, 0)
5567 ZEND_ARG_INFO(0, "parser")
5568 ZEND_ARG_INFO(0, "holders")
5569 ZEND_ARG_INFO(0, "markers")
5570 ZEND_ARG_INFO(0, "title")
5571 ZEND_ARG_INFO(0, "titleText")
5572 ZEND_ARG_INFO(1, "sortText")
5573 ZEND_ARG_INFO(1, "leadingColon")
5576 static function_entry CoreLinkFunctions_functions
[] = {
5577 PHP_ME(CoreLinkFunctions
, register, CoreLinkFunctions_register_arg_info
, ZEND_ACC_PUBLIC
| ZEND_ACC_STATIC
)
5578 PHP_ME(CoreLinkFunctions
, defaultlinkhook
, CoreLinkFunctions_defaultlinkhook_arg_info
, ZEND_ACC_PUBLIC
| ZEND_ACC_STATIC
)
5579 PHP_ME(CoreLinkFunctions
, categorylinkhook
, CoreLinkFunctions_categorylinkhook_arg_info
, ZEND_ACC_PUBLIC
| ZEND_ACC_STATIC
)
5580 { NULL
, NULL
, NULL
}
5582 // function __MAIN__()
5585 PHP_FUNCTION(__MAIN__
)
5589 end_of_function
:__attribute__((unused
));
5591 // Module initialization
5592 PHP_MINIT_FUNCTION(app
)
5595 zend_class_entry ce
; // temp
5596 zend_class_entry
* ce_reg
; // once registered, ce_ptr should be used
5597 INIT_CLASS_ENTRY(ce
, "CoreLinkFunctions", CoreLinkFunctions_functions
);
5598 ce_reg
= zend_register_internal_class(&ce TSRMLS_CC
);
5599 ce_reg
->type
&= ~ZEND_INTERNAL_CLASS
;
5600 }return SUCCESS
;}// ArgInfo structures (necessary to support compile time pass-by-reference)
5601 ZEND_BEGIN_ARG_INFO_EX(app___MAIN___arg_info
, 0, 0, 0)
5604 static function_entry app_functions
[] = {
5605 PHP_FE(__MAIN__
, app___MAIN___arg_info
)
5606 { NULL
, NULL
, NULL
}
5608 // Register the module itself with PHP
5609 zend_module_entry app_module_entry
= {
5610 STANDARD_MODULE_HEADER
,
5613 PHP_MINIT(app
), /* MINIT */
5614 NULL
, /* MSHUTDOWN */
5616 NULL
, /* RSHUTDOWN */
5619 STANDARD_MODULE_PROPERTIES
5621 #include <sapi/embed/php_embed.h>
5624 void sighandler(int signum
)
5629 printf("SIGABRT received!\n");
5632 printf("SIGSEGV received!\n");
5635 printf("Unknown signal received!\n");
5639 printf("This could be a bug in phc. If you suspect it is, please email\n");
5640 printf("a bug report to phc-general@phpcompiler.org.\n");
5645 main (int argc
, char* argv
[])
5647 int phc_exit_status
;
5648 signal(SIGABRT
, sighandler
);
5649 signal(SIGSEGV
, sighandler
);
5652 int dealloc_pools
= 1;
5653 php_embed_init (argc
, argv PTSRMLS_CC
);
5657 // initialize the phc runtime
5660 // load the compiled extension
5661 zend_startup_module (&app_module_entry
);
5664 ZVAL_STRING (&main_name
, "__MAIN__", NULL
);
5668 // Use standard errors, on stdout
5669 zend_alter_ini_entry ("report_zend_debug", sizeof("report_zend_debug"), "0", sizeof("0") - 1, PHP_INI_ALL
, PHP_INI_STAGE_RUNTIME
);
5670 zend_alter_ini_entry ("display_startup_errors", sizeof("display_startup_errors"), "1", sizeof("1") - 1, PHP_INI_ALL
, PHP_INI_STAGE_RUNTIME
);
5672 // initialize all the constants
5676 int success
= call_user_function(
5677 EG (function_table
),
5685 assert (success
== SUCCESS
);
5687 // finalize the runtime
5699 phc_exit_status
= EG(exit_status
);
5700 php_embed_shutdown (TSRMLS_C
);
5702 return phc_exit_status
;