]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-5.6'
authorXinchen Hui <laruence@php.net>
Fri, 13 Feb 2015 05:18:14 +0000 (13:18 +0800)
committerXinchen Hui <laruence@php.net>
Fri, 13 Feb 2015 05:28:24 +0000 (13:28 +0800)
Conflicts:
ext/soap/soap.c
ext/standard/basic_functions.c
ext/zlib/zlib.c

1  2 
Zend/zend_compile.c
Zend/zend_compile.h
ext/filter/filter.c
ext/soap/soap.c
ext/standard/basic_functions.c
ext/standard/browscap.c
ext/zlib/zlib.c
sapi/cli/php_cli.c
sapi/phpdbg/phpdbg_utils.c

index 90c7ec34b3220fdde9fccd2f4794c7697b41c980,c513e2ff88adb8fb1ce31a9ef48eff64acad86e6..c9b67021f05ecb748a11bf5749edd8b83a3fe884
@@@ -1199,81 -1532,262 +1199,82 @@@ static zend_bool zend_try_ct_eval_const
  }
  /* }}} */
  
 -void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC) /* {{{ */
 +static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend_string *name) /* {{{ */
  {
 -      zend_op_array op_array;
 -      char *name = Z_STRVAL(function_name->u.constant);
 -      int name_len = Z_STRLEN(function_name->u.constant);
 -      int function_begin_line = function_token->u.op.opline_num;
 -      zend_uint fn_flags;
 -      const char *lcname;
 -      zend_bool orig_interactive;
 -      ALLOCA_FLAG(use_heap)
 +      uint32_t fetch_type = zend_get_class_fetch_type(class_name);
 +      zval *c;
  
 -      if (is_method) {
 -              if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
 -                      if ((Z_LVAL(fn_flags_znode->u.constant) & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) {
 -                              zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method %s::%s() must be omitted", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant));
 -                      }
 -                      Z_LVAL(fn_flags_znode->u.constant) |= ZEND_ACC_ABSTRACT; /* propagates to the rest of the parser */
 +      if (CG(active_class_entry) && (fetch_type == ZEND_FETCH_CLASS_SELF || (fetch_type == ZEND_FETCH_CLASS_DEFAULT && zend_string_equals_ci(class_name, CG(active_class_entry)->name)))) {
 +              c = zend_hash_find(&CG(active_class_entry)->constants_table, name);
 +      } else if (fetch_type == ZEND_FETCH_CLASS_DEFAULT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
 +              zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), class_name->val, class_name->len);
 +              if (ce) {
 +                      c = zend_hash_find(&ce->constants_table, name);
 +              } else {
 +                      return 0;
                }
 -              fn_flags = Z_LVAL(fn_flags_znode->u.constant); /* must be done *after* the above check */
        } else {
 -              fn_flags = 0;
 -      }
 -      if ((fn_flags & ZEND_ACC_STATIC) && (fn_flags & ZEND_ACC_ABSTRACT) && !(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) {
 -              zend_error(E_STRICT, "Static function %s%s%s() should not be abstract", is_method ? CG(active_class_entry)->name : "", is_method ? "::" : "", Z_STRVAL(function_name->u.constant));
 +              return 0;
        }
  
 -      function_token->u.op_array = CG(active_op_array);
 -
 -      orig_interactive = CG(interactive);
 -      CG(interactive) = 0;
 -      init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
 -      CG(interactive) = orig_interactive;
 -
 -      op_array.function_name = name;
 -      if (return_reference) {
 -              op_array.fn_flags |= ZEND_ACC_RETURN_REFERENCE;
 +      if (CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) {
 +              return 0;
        }
 -      op_array.fn_flags |= fn_flags;
 -
 -      op_array.scope = is_method?CG(active_class_entry):NULL;
 -      op_array.prototype = NULL;
 -
 -      op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
 -
 -      if (is_method) {
 -              zend_ulong hash;
 -
 -              lcname = zend_new_interned_string(zend_str_tolower_dup(name, name_len), name_len + 1, 1 TSRMLS_CC);
 -              hash = str_hash(lcname, name_len);
 -              if (zend_hash_quick_add(&CG(active_class_entry)->function_table, lcname, name_len+1, hash, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
 -                      zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name);
 -              }
 -
 -              zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
 -              zend_init_compiler_context(TSRMLS_C);
 -
 -              if (fn_flags & ZEND_ACC_ABSTRACT) {
 -                      CG(active_class_entry)->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
 -              }
 -
 -              if (!(fn_flags & ZEND_ACC_PPP_MASK)) {
 -                      fn_flags |= ZEND_ACC_PUBLIC;
 -              }
 -
 -              if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
 -                      if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __call() must have public visibility and cannot be static");
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) {
 -                              if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) {
 -                                      zend_error(E_WARNING, "The magic method __callStatic() must have public visibility and be static");
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __get() must have public visibility and cannot be static");
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __set() must have public visibility and cannot be static");
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __unset() must have public visibility and cannot be static");
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __isset() must have public visibility and cannot be static");
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static");
 -                              }
 -
 -                      } else if ((name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __debugInfo() must have public visibility and cannot be static");
 -                              }
 -                      }
 -              } else {
 -                      char *class_lcname;
  
 -                      class_lcname = do_alloca(CG(active_class_entry)->name_length + 1, use_heap);
 -                      zend_str_tolower_copy(class_lcname, CG(active_class_entry)->name, CG(active_class_entry)->name_length);
 -                      /* Improve after RC: cache the lowercase class name */
 +      /* Substitute case-sensitive (or lowercase) persistent class constants */
 +      if (c && Z_TYPE_P(c) < IS_OBJECT) {
 +              ZVAL_DUP(zv, c);
 +              return 1;
 +      }
  
 -                      if ((CG(active_class_entry)->name_length == name_len) && ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != ZEND_ACC_TRAIT) && (!memcmp(class_lcname, lcname, name_len))) {
 -                              if (!CG(active_class_entry)->constructor) {
 -                                      CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array);
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)))) {
 -                              if (CG(active_class_entry)->constructor) {
 -                                      zend_error(E_STRICT, "Redefining already defined constructor for class %s", CG(active_class_entry)->name);
 -                              }
 -                              CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1))) {
 -                              CG(active_class_entry)->destructor = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1))) {
 -                              CG(active_class_entry)->clone = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __call() must have public visibility and cannot be static");
 -                              }
 -                              CG(active_class_entry)->__call = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) {
 -                              if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) {
 -                                      zend_error(E_WARNING, "The magic method __callStatic() must have public visibility and be static");
 -                              }
 -                              CG(active_class_entry)->__callstatic = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __get() must have public visibility and cannot be static");
 -                              }
 -                              CG(active_class_entry)->__get = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __set() must have public visibility and cannot be static");
 -                              }
 -                              CG(active_class_entry)->__set = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __unset() must have public visibility and cannot be static");
 -                              }
 -                              CG(active_class_entry)->__unset = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __isset() must have public visibility and cannot be static");
 -                              }
 -                              CG(active_class_entry)->__isset = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
 -                              }
 -                              CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array);
 -                      } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static");
 -                              }
 -                      } else if ((name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) {
 -                              if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
 -                                      zend_error(E_WARNING, "The magic method __debugInfo() must have public visibility and cannot be static");
 -                              }
 -                              CG(active_class_entry)->__debugInfo = (zend_function *) CG(active_op_array);
 -                      } else if (!(fn_flags & ZEND_ACC_STATIC)) {
 -                              CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC;
 -                      }
 -                      free_alloca(class_lcname, use_heap);
 -              }
 +      return 0;
 +}
++/* }}} */
  
 -              str_efree(lcname);
 -      } else {
 -              zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 -              zval key;
 -              zval **ns_name;
 +void zend_init_list(void *result, void *item) /* {{{ */
 +{
 +      void** list = emalloc(sizeof(void*) * 2);
  
 -              if (CG(current_namespace)) {
 -                      /* Prefix function name with current namespace name */
 -                      znode tmp;
 -
 -                      tmp.u.constant = *CG(current_namespace);
 -                      zval_copy_ctor(&tmp.u.constant);
 -                      zend_do_build_namespace_name(&tmp, &tmp, function_name TSRMLS_CC);
 -                      op_array.function_name = Z_STRVAL(tmp.u.constant);
 -                      name_len = Z_STRLEN(tmp.u.constant);
 -                      lcname = zend_str_tolower_dup(Z_STRVAL(tmp.u.constant), name_len);
 -              } else {
 -                      lcname = zend_str_tolower_dup(name, name_len);
 -              }
 +      list[0] = item;
 +      list[1] = NULL;
  
 -              /* Function name must not conflict with import names */
 -              if (CG(current_import_function) &&
 -                  zend_hash_find(CG(current_import_function), lcname, Z_STRLEN(function_name->u.constant)+1, (void**)&ns_name) == SUCCESS) {
 +      *(void**)result = list;
 +}
 +/* }}} */
  
 -                      char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name));
 +void zend_add_to_list(void *result, void *item) /* {{{ */
 +{
 +      void** list = *(void**)result;
 +      size_t n = 0;
  
 -                      if (Z_STRLEN_PP(ns_name) != Z_STRLEN(function_name->u.constant) ||
 -                              memcmp(tmp, lcname, Z_STRLEN(function_name->u.constant))) {
 -                              zend_error(E_COMPILE_ERROR, "Cannot declare function %s because the name is already in use", Z_STRVAL(function_name->u.constant));
 -                      }
 -                      efree(tmp);
 +      if (list) {
 +              while (list[n]) {
 +                      n++;
                }
 -
 -              opline->opcode = ZEND_DECLARE_FUNCTION;
 -              opline->op1_type = IS_CONST;
 -              build_runtime_defined_function_key(&key, lcname, name_len TSRMLS_CC);
 -              opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
 -              Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)));
 -              opline->op2_type = IS_CONST;
 -              LITERAL_STRINGL(opline->op2, lcname, name_len, 1);
 -              CALCULATE_LITERAL_HASH(opline->op2.constant);
 -              opline->extended_value = ZEND_DECLARE_FUNCTION;
 -              zend_hash_quick_update(CG(function_table), Z_STRVAL(key), Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array));
 -              zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
 -              zend_init_compiler_context(TSRMLS_C);
 -              str_efree(lcname);
        }
  
 -      if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
 -              zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 +      list = erealloc(list, sizeof(void*) * (n+2));
  
 -              opline->opcode = ZEND_EXT_NOP;
 -              opline->lineno = function_begin_line;
 -              SET_UNUSED(opline->op1);
 -              SET_UNUSED(opline->op2);
 -      }
 +      list[n]   = item;
 +      list[n+1] = NULL;
  
 -      {
 -              /* Push a separator to the switch stack */
 -              zend_switch_entry switch_entry;
 +      *(void**)result = list;
 +}
 +/* }}} */
  
 -              switch_entry.cond.op_type = IS_UNUSED;
 -              switch_entry.default_case = 0;
 -              switch_entry.control_var = 0;
 +void zend_do_extended_info(void) /* {{{ */
 +{
 +      zend_op *opline;
  
 -              zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
 +      if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
 +              return;
        }
  
 -      {
 -              /* Push a separator to the foreach stack */
 -              zend_op dummy_opline;
 -
 -              dummy_opline.result_type = IS_UNUSED;
 -
 -              zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
 -      }
 +      opline = get_next_op(CG(active_op_array));
  
 -      if (CG(doc_comment)) {
 -              CG(active_op_array)->doc_comment = CG(doc_comment);
 -              CG(active_op_array)->doc_comment_len = CG(doc_comment_len);
 -              CG(doc_comment) = NULL;
 -              CG(doc_comment_len) = 0;
 -      }
 +      opline->opcode = ZEND_EXT_STMT;
 +      SET_UNUSED(opline->op1);
 +      SET_UNUSED(opline->op2);
  }
  /* }}} */
  
@@@ -1309,17 -1828,151 +1310,30 @@@ void zend_do_extended_fcall_end(void) /
  }
  /* }}} */
  
 -void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* {{{ */
 -{
 -      char lcname[16];
 -      int name_len;
 -
 -      zend_do_extended_info(TSRMLS_C);
 -      zend_do_return(NULL, 0 TSRMLS_CC);
 -
 -      pass_two(CG(active_op_array) TSRMLS_CC);
 -      zend_release_labels(0 TSRMLS_CC);
++zend_bool zend_is_auto_global_str(char *name, size_t len) /* {{{ */ {
++      zend_auto_global *auto_global;
 -      if (CG(active_class_entry)) {
 -              zend_check_magic_method_implementation(CG(active_class_entry), (zend_function*)CG(active_op_array), E_COMPILE_ERROR TSRMLS_CC);
 -      } else {
 -              /* we don't care if the function name is longer, in fact lowercasing only
 -               * the beginning of the name speeds up the check process */
 -              name_len = strlen(CG(active_op_array)->function_name);
 -              zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1));
 -              lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
 -              if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)) && CG(active_op_array)->num_args != 1) {
 -                      zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME);
++      if ((auto_global = zend_hash_str_find_ptr(CG(auto_globals), name, len)) != NULL) {
++              if (auto_global->armed) {
++                      auto_global->armed = auto_global->auto_global_callback(auto_global->name);
+               }
++              return 1;
+       }
 -
 -      CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C);
 -      CG(active_op_array) = function_token->u.op_array;
 -
 -
 -      /* Pop the switch and foreach separators */
 -      zend_stack_del_top(&CG(switch_cond_stack));
 -      zend_stack_del_top(&CG(foreach_copy_stack));
++      return 0;
+ }
+ /* }}} */
 -void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_uchar pass_by_reference, zend_bool is_variadic TSRMLS_DC) /* {{{ */
 +zend_bool zend_is_auto_global(zend_string *name) /* {{{ */
  {
 -      zend_op *opline;
 -      zend_arg_info *cur_arg_info;
 -      znode var;
 +      zend_auto_global *auto_global;
  
 -      if (zend_is_auto_global(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant) TSRMLS_CC)) {
 -              zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s", Z_STRVAL(varname->u.constant));
 -      } else {
 -              var.op_type = IS_CV;
 -              var.u.op.var = lookup_cv(CG(active_op_array), Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), 0 TSRMLS_CC);
 -              Z_STRVAL(varname->u.constant) = (char*)CG(active_op_array)->vars[var.u.op.var].name;
 -              var.EA = 0;
 -              if (CG(active_op_array)->vars[var.u.op.var].hash_value == THIS_HASHVAL &&
 -                      Z_STRLEN(varname->u.constant) == sizeof("this")-1 &&
 -                  !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")-1)) {
 -                      if (CG(active_op_array)->scope &&
 -                          (CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) {
 -                              zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
 -                      }
 -                      CG(active_op_array)->this_var = var.u.op.var;
 -              }
 -      }
 -
 -      if (CG(active_op_array)->fn_flags & ZEND_ACC_VARIADIC) {
 -              zend_error_noreturn(E_COMPILE_ERROR, "Only the last parameter can be variadic");
 -      }
 -
 -      if (is_variadic) {
 -              if (op == ZEND_RECV_INIT) {
 -                      zend_error_noreturn(E_COMPILE_ERROR, "Variadic parameter cannot have a default value");
 -              }
 -
 -              op = ZEND_RECV_VARIADIC;
 -              CG(active_op_array)->fn_flags |= ZEND_ACC_VARIADIC;
 -      }
 -
 -      opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 -      CG(active_op_array)->num_args++;
 -      opline->opcode = op;
 -      SET_NODE(opline->result, &var);
 -      opline->op1_type = IS_UNUSED;
 -      opline->op1.num = CG(active_op_array)->num_args;
 -      if (op == ZEND_RECV_INIT) {
 -              SET_NODE(opline->op2, initialization);
 -      } else {
 -              SET_UNUSED(opline->op2);
 -              if (!is_variadic) {
 -                      CG(active_op_array)->required_num_args = CG(active_op_array)->num_args;
 -              }
 -      }
 -      CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
 -      cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
 -      cur_arg_info->name = zend_new_interned_string(estrndup(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)), Z_STRLEN(varname->u.constant) + 1, 1 TSRMLS_CC);
 -      cur_arg_info->name_len = Z_STRLEN(varname->u.constant);
 -      cur_arg_info->type_hint = 0;
 -      cur_arg_info->pass_by_reference = pass_by_reference;
 -      cur_arg_info->allow_null = 1;
 -      cur_arg_info->is_variadic = is_variadic;
 -      cur_arg_info->class_name = NULL;
 -      cur_arg_info->class_name_len = 0;
 -
 -      if (class_type->op_type != IS_UNUSED) {
 -              cur_arg_info->allow_null = 0;
 -
 -              if (class_type->u.constant.type != IS_NULL) {
 -                      if (class_type->u.constant.type == IS_ARRAY) {
 -                              cur_arg_info->type_hint = IS_ARRAY;
 -                              if (op == ZEND_RECV_INIT) {
 -                                      if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
 -                                              cur_arg_info->allow_null = 1;
 -                                      } else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) {
 -                                              /* delay constant resolution and check to run-time */
 -                                              cur_arg_info->allow_null = 0;
 -                                      } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY) {
 -                                              zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL");
 -                                      }
 -                              }
 -                      } else if (class_type->u.constant.type == IS_CALLABLE) {
 -                              cur_arg_info->type_hint = IS_CALLABLE;
 -                              if (op == ZEND_RECV_INIT) {
 -                                      if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
 -                                              cur_arg_info->allow_null = 1;
 -                                      } else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) {
 -                                              /* delay constant resolution and check to run-time */
 -                                              cur_arg_info->allow_null = 0;
 -                                      } else {
 -                                              zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL");
 -                                      }
 -                              }
 -                      } else {
 -                              cur_arg_info->type_hint = IS_OBJECT;
 -                              if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) {
 -                                      zend_resolve_class_name(class_type TSRMLS_CC);
 -                              }
 -                              Z_STRVAL(class_type->u.constant) = (char*)zend_new_interned_string(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant) + 1, 1 TSRMLS_CC);
 -                              cur_arg_info->class_name = Z_STRVAL(class_type->u.constant);
 -                              cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant);
 -                              if (op == ZEND_RECV_INIT) {
 -                                      if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
 -                                              cur_arg_info->allow_null = 1;
 -                                      } else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) {
 -                                              /* delay constant resolution and check to run-time */
 -                                              cur_arg_info->allow_null = 0;
 -                                      } else {
 -                                              zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL");
 -                                      }
 -                              }
 -                      }
 +      if ((auto_global = zend_hash_find_ptr(CG(auto_globals), name)) != NULL) {
 +              if (auto_global->armed) {
 +                      auto_global->armed = auto_global->auto_global_callback(auto_global->name);
                }
 +              return 1;
        }
 +      return 0;
  }
  /* }}} */
  
index 1104a29b826b1e5c139538dd47f3e4c409dcff53,3e9992f15b107ead4672935025a2ced2d6476f08..0a4c146d28c4f6f70fb4cb39cc5c159a7e50e31e
@@@ -727,14 -726,15 +727,15 @@@ typedef struct _zend_auto_global 
        zend_bool armed;
  } zend_auto_global;
  
 -ZEND_API int zend_register_auto_global(const char *name, uint name_len, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC);
 -ZEND_API void zend_activate_auto_globals(TSRMLS_D);
 -ZEND_API zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC);
 -ZEND_API zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hashval TSRMLS_DC);
 +ZEND_API int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback);
 +ZEND_API void zend_activate_auto_globals(void);
 +ZEND_API zend_bool zend_is_auto_global(zend_string *name);
++ZEND_API zend_bool zend_is_auto_global_str(char *name, size_t len);
  ZEND_API size_t zend_dirname(char *path, size_t len);
  
 -int zendlex(znode *zendlval TSRMLS_DC);
 +int zendlex(zend_parser_stack_elem *elem);
  
 -int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
 +int zend_add_literal(zend_op_array *op_array, zval *zv);
  
  /* BEGIN: OPCODES */
  
index 85cfbf091395a26b34441a4ddc9e03b3508d448f,86120bba568c551914a35636ec408f1e7e66af32..9e2613257e9c07ffdd1f69218a15d5d4c03972ce
@@@ -534,19 -540,15 +534,15 @@@ static zval *php_filter_get_storage(zen
                        break;
                case PARSE_SERVER:
                        if (PG(auto_globals_jit)) {
-                               zend_string *name = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
-                               zend_is_auto_global(name);
-                               zend_string_release(name);
 -                              zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
++                              zend_is_auto_global_str(ZEND_STRL("_SERVER"));
                        }
 -                      array_ptr = IF_G(server_array);
 +                      array_ptr = &IF_G(server_array);
                        break;
                case PARSE_ENV:
                        if (PG(auto_globals_jit)) {
-                               zend_string *name = zend_string_init("_ENV", sizeof("_ENV") - 1, 0);
-                               zend_is_auto_global(name);
-                               zend_string_release(name);
 -                              zend_is_auto_global("_ENV", sizeof("_ENV")-1 TSRMLS_CC);
++                              zend_is_auto_global_str(ZEND_STRL("_ENV"));
                        }
 -                      array_ptr = IF_G(env_array) ? IF_G(env_array) : PG(http_globals)[TRACK_VARS_ENV];
 +                      array_ptr = &IF_G(env_array) ? &IF_G(env_array) : &PG(http_globals)[TRACK_VARS_ENV];
                        break;
                case PARSE_SESSION:
                        /* FIXME: Implement session source */
diff --cc ext/soap/soap.c
index 4308f3885f76fe5a927c2d5be70f00c7069cf9ad,406fdc0f54d33e7bd9cf44fed760fc71d43823ee..6792c325ac0e5cc803f6b35a8090e79fabe0c4e6
@@@ -1566,19 -1568,18 +1566,19 @@@ PHP_METHOD(SoapServer, handle
  
        if (ZEND_NUM_ARGS() == 0) {
                if (SG(request_info).request_body && 0 == php_stream_rewind(SG(request_info).request_body)) {
 -                      zval **server_vars, **encoding;
 +                      zval *server_vars, *encoding;
                        php_stream_filter *zf = NULL;
-                       zend_string *server = zend_string_init("_SERVER", sizeof("_SERVER")-1, 0);
++                      zend_string *server = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
  
 -                      zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
 -                      if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS &&
 -                          Z_TYPE_PP(server_vars) == IS_ARRAY &&
 -                          zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING"), (void **) &encoding)==SUCCESS &&
 -                          Z_TYPE_PP(encoding) == IS_STRING) {
 +                      zend_is_auto_global(server);
 +                      if ((server_vars = zend_hash_find(&EG(symbol_table).ht, server)) != NULL &&
 +                          Z_TYPE_P(server_vars) == IS_ARRAY &&
 +                          (encoding = zend_hash_str_find(Z_ARRVAL_P(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING")-1)) != NULL &&
 +                          Z_TYPE_P(encoding) == IS_STRING) {
  
 -                              if (strcmp(Z_STRVAL_PP(encoding),"gzip") == 0
 -                              ||  strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 0
 -                              ||  strcmp(Z_STRVAL_PP(encoding),"deflate") == 0
 +                              if (strcmp(Z_STRVAL_P(encoding),"gzip") == 0
 +                              ||  strcmp(Z_STRVAL_P(encoding),"x-gzip") == 0
 +                              ||  strcmp(Z_STRVAL_P(encoding),"deflate") == 0
                                ) {
                                        zval filter_params;
  
@@@ -2089,12 -2070,10 +2089,10 @@@ static void soap_server_fault_ex(sdlFun
  
        xmlDocDumpMemory(doc_return, &buf, &size);
  
-       server = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
-       zend_is_auto_global(server);
-       if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF &&
 -      if ((PG(http_globals)[TRACK_VARS_SERVER] || zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC)) &&
 -              zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->value.ht, "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &agent_name) == SUCCESS &&
 -              Z_TYPE_PP(agent_name) == IS_STRING) {
 -              if (strncmp(Z_STRVAL_PP(agent_name), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) {
++      if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
 +              (agent_name = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1)) != NULL &&
 +              Z_TYPE_P(agent_name) == IS_STRING) {
 +              if (strncmp(Z_STRVAL_P(agent_name), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) {
                        use_http_error_status = 0;
                }
        }
index 940c9e414175058440b2f3d9cc9491c79348fdc8,6552596438898f1db90edf9f825e3885bc52d078..dcd054fadb569cef078e2bf5521cb68ce6ea4d46
@@@ -4229,17 -4227,14 +4229,17 @@@ PHP_FUNCTION(getopt
        /* Get argv from the global symbol table. We calculate argc ourselves
         * in order to be on the safe side, even though it is also available
         * from the symbol table. */
-       if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF &&
 -      if ((PG(http_globals)[TRACK_VARS_SERVER] || zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC)) &&
 -              (zend_hash_find(Z_ARRVAL_P((PG(http_globals))[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE ||
 -              zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void **) &args) != FAILURE) && Z_TYPE_PP(args) == IS_ARRAY
++      if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
 +              ((args = zend_hash_str_find_ind(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1)) != NULL ||
 +              (args = zend_hash_str_find_ind(&EG(symbol_table).ht, "argv", sizeof("argv")-1)) != NULL)
        ) {
                int pos = 0;
 -              zval **entry;
 +              zval *entry;
  
 -              argc = zend_hash_num_elements(Z_ARRVAL_PP(args));
 +              if (Z_TYPE_P(args) != IS_ARRAY) {
 +                      RETURN_FALSE;
 +              }
 +              argc = zend_hash_num_elements(Z_ARRVAL_P(args));
  
                /* Attempt to allocate enough memory to hold all of the arguments
                 * and a trailing NULL */
index e88a09e883ca214f6437b6c05a9bec1339b990e9,d3a094fdfb14ca49d9ce6fe7590338e09203a959..217437ba8f2b473530ce7b5d71965ca0146004b7
@@@ -462,17 -496,15 +462,14 @@@ PHP_FUNCTION(get_browser
        }
  
        if (agent_name == NULL) {
-               zend_string *key = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
-               zend_is_auto_global(key);
-               zend_string_release(key);
-               if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF ||
-                       (http_user_agent = zend_hash_str_find(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1)) == NULL
 -              zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC);
 -              if (!PG(http_globals)[TRACK_VARS_SERVER] ||
 -                      zend_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &http_user_agent) == FAILURE
++              if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) ||
++                      (http_user_agent = zend_hash_str_find(Z_ARRVAL_P(&PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1)) == NULL
                ) {
 -                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "HTTP_USER_AGENT variable is not set, cannot determine user agent name");
 +                      php_error_docref(NULL, E_WARNING, "HTTP_USER_AGENT variable is not set, cannot determine user agent name");
                        RETURN_FALSE;
                }
 -              agent_name = Z_STRVAL_PP(http_user_agent);
 -              agent_name_len = Z_STRLEN_PP(http_user_agent);
 +              agent_name = Z_STRVAL_P(http_user_agent);
 +              agent_name_len = Z_STRLEN_P(http_user_agent);
        }
  
        lookup_browser_name = estrndup(agent_name, agent_name_len);
diff --cc ext/zlib/zlib.c
index 0b082048c07498b6d97067c068eafec1a302f327,d70198c674317ce36384f67b143f25cbcc488dd0..67e67b114eab33cc877f639f926acf180716616c
@@@ -77,20 -77,17 +77,17 @@@ static int php_zlib_output_conflict_che
  /* }}} */
  
  /* {{{ php_zlib_output_encoding() */
 -static int php_zlib_output_encoding(TSRMLS_D)
 +static int php_zlib_output_encoding(void)
  {
 -      zval **enc;
 +      zval *enc;
  
        if (!ZLIBG(compression_coding)) {
-               zend_string *name = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
-               zend_is_auto_global(name);
-               zend_string_release(name);
-               if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY &&
 -              if ((PG(http_globals)[TRACK_VARS_SERVER]  || zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC)) && 
 -                              SUCCESS == zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING"), (void *) &enc)) {
 -                      convert_to_string(*enc);
 -                      if (strstr(Z_STRVAL_PP(enc), "gzip")) {
++              if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
 +                      (enc = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING") - 1))) {
 +                      convert_to_string(enc);
 +                      if (strstr(Z_STRVAL_P(enc), "gzip")) {
                                ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_GZIP;
 -                      } else if (strstr(Z_STRVAL_PP(enc), "deflate")) {
 +                      } else if (strstr(Z_STRVAL_P(enc), "deflate")) {
                                ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_DEFLATE;
                        }
                }
index ca0ea57fa7be8a14d9362be6904f5ce2a94e7903,db5ddb2567a0f288d58bf7b7ef08caa41ea1bb9d..8a8e113db0fa7b19d880fe0ec2bfd288aadffd58
@@@ -661,11 -673,11 +661,10 @@@ static int do_cli(int argc, char **argv
        int lineno = 0;
        const char *param_error=NULL;
        int hide_argv = 0;
-       zend_string *key;
  
        zend_try {
 -      
 +
                CG(in_compilation) = 0; /* not initialized but needed for several options */
 -              EG(uninitialized_zval_ptr) = NULL;
  
                while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
                        switch (c) {
                        }
                }
  
-               key = zend_string_init("_SERVER", sizeof("_SERVER")-1, 0);
-               zend_is_auto_global(key);
-               zend_string_release(key);
 -              zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
++              zend_is_auto_global_str(ZEND_STRL("_SERVER"));
  
                PG(during_request_startup) = 0;
                switch (behavior) {
index 357905fa06efae6224d07176077712e41a14f18d,7c7307a58b3b7305da1b36e4f19798720354d18c..ecec950c1bd8fb41927b5af0f2c46e5e1203b12e
@@@ -343,328 -453,3 +343,324 @@@ PHPDBG_API int phpdbg_get_terminal_widt
  #endif
        return columns;
  } /* }}} */
-       int ret;
-       zend_string *str = zend_string_init(name, len, 0);
-       ret = zend_is_auto_global(str);
-       efree(str);
-       return ret;
 +
 +PHPDBG_API void phpdbg_set_async_io(int fd) {
 +#ifndef _WIN32
 +      int flags;
 +      fcntl(STDIN_FILENO, F_SETOWN, getpid());
 +      flags = fcntl(STDIN_FILENO, F_GETFL);
 +      fcntl(STDIN_FILENO, F_SETFL, flags | FASYNC);
 +#endif
 +}
 +
 +int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry **ce) {
 +      if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
 +              char *lc_name, *lc_free;
 +              int lc_length;
 +
 +              if (name == NULL || !name_length) {
 +                      return FAILURE;
 +              }
 +
 +              lc_free = lc_name = emalloc(name_length + 1);
 +              zend_str_tolower_copy(lc_name, name, name_length);
 +              lc_length = name_length + 1;
 +
 +              if (lc_name[0] == '\\') {
 +                      lc_name += 1;
 +                      lc_length -= 1;
 +              }
 +
 +              phpdbg_try_access {
 +                      *ce = zend_hash_str_find_ptr(EG(class_table), lc_name, lc_length);
 +              } phpdbg_catch_access {
 +                      phpdbg_error("signalsegv", "class=\"%.*s\"", "Could not fetch class %.*s, invalid data source", name_length, name);
 +              } phpdbg_end_try_access();
 +
 +              efree(lc_free);
 +      } else {
 +              zend_string *str_name = zend_string_init(name, name_length, 0);
 +              *ce = zend_lookup_class(str_name);
 +              efree(str_name);
 +      }
 +
 +      return ce ? SUCCESS : FAILURE;
 +}
 +
 +char *phpdbg_get_property_key(char *key) {
 +      if (*key != 0) {
 +              return key;
 +      }
 +      return strchr(key + 1, 0) + 1;
 +}
 +
 +static int phpdbg_parse_variable_arg_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv, phpdbg_parse_var_func callback) {
 +      return callback(name, len, keyname, keylen, parent, zv);
 +}
 +
 +PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, zend_bool silent) {
 +      return phpdbg_parse_variable_with_arg(input, len, parent, i, (phpdbg_parse_var_with_arg_func) phpdbg_parse_variable_arg_wrapper, silent, callback);
 +}
 +
 +PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, zend_bool silent, void *arg) {
 +      int ret = FAILURE;
 +      zend_bool new_index = 1;
 +      char *last_index;
 +      size_t index_len = 0;
 +      zval *zv;
 +
 +      if (len < 2 || *input != '$') {
 +              goto error;
 +      }
 +
 +      while (i++ < len) {
 +              if (i == len) {
 +                      new_index = 1;
 +              } else {
 +                      switch (input[i]) {
 +                              case '[':
 +                                      new_index = 1;
 +                                      break;
 +                              case ']':
 +                                      break;
 +                              case '>':
 +                                      if (last_index[index_len - 1] == '-') {
 +                                              new_index = 1;
 +                                              index_len--;
 +                                      }
 +                                      break;
 +
 +                              default:
 +                                      if (new_index) {
 +                                              last_index = input + i;
 +                                              new_index = 0;
 +                                      }
 +                                      if (input[i - 1] == ']') {
 +                                              goto error;
 +                                      }
 +                                      index_len++;
 +                      }
 +              }
 +
 +              if (new_index && index_len == 0) {
 +                      zend_ulong numkey;
 +                      zend_string *strkey;
 +                      ZEND_HASH_FOREACH_KEY_PTR(parent, numkey, strkey, zv) {
 +                              while (Z_TYPE_P(zv) == IS_INDIRECT) {
 +                                      zv = Z_INDIRECT_P(zv);
 +                              }
 +
 +                              if (i == len || (i == len - 1 && input[len - 1] == ']')) {
 +                                      char *key, *propkey;
 +                                      size_t namelen, keylen;
 +                                      char *name;
 +                                      char *keyname = estrndup(last_index, index_len);
 +                                      if (strkey) {
 +                                              key = strkey->val;
 +                                              keylen = strkey->len;
 +                                      } else {
 +                                              keylen = spprintf(&key, 0, "%llu", numkey);
 +                                      }
 +                                      propkey = phpdbg_get_property_key(key);
 +                                      name = emalloc(i + keylen + 2);
 +                                      namelen = sprintf(name, "%.*s%.*s%s", (int) i, input, keylen - (propkey - key), propkey, input[len - 1] == ']'?"]":"");
 +                                      if (!strkey) {
 +                                              efree(key);
 +                                      }
 +
 +                                      ret = callback(name, namelen, keyname, index_len, parent, zv, arg) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE;
 +                              } else if (Z_TYPE_P(zv) == IS_OBJECT) {
 +                                      phpdbg_parse_variable_with_arg(input, len, Z_OBJPROP_P(zv), i, callback, silent, arg);
 +                              } else if (Z_TYPE_P(zv) == IS_ARRAY) {
 +                                      phpdbg_parse_variable_with_arg(input, len, Z_ARRVAL_P(zv), i, callback, silent, arg);
 +                              } else {
 +                                      /* Ignore silently */
 +                              }
 +                      } ZEND_HASH_FOREACH_END();
 +                      return ret;
 +              } else if (new_index) {
 +                      char last_chr = last_index[index_len];
 +                      last_index[index_len] = 0;
 +                      if (!(zv = zend_symtable_str_find(parent, last_index, index_len))) {
 +                              if (!silent) {
 +                                      phpdbg_error("variable", "type=\"undefined\" variable=\"%.*s\"", "%.*s is undefined", (int) i, input);
 +                              }
 +                              return FAILURE;
 +                      }
 +                      while (Z_TYPE_P(zv) == IS_INDIRECT) {
 +                              zv = Z_INDIRECT_P(zv);
 +                      }
 +
 +                      last_index[index_len] = last_chr;
 +                      if (i == len) {
 +                              char *name = estrndup(input, len);
 +                              char *keyname = estrndup(last_index, index_len);
 +
 +                              ret = callback(name, len, keyname, index_len, parent, zv, arg) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE;
 +                      } else if (Z_TYPE_P(zv) == IS_OBJECT) {
 +                              parent = Z_OBJPROP_P(zv);
 +                      } else if (Z_TYPE_P(zv) == IS_ARRAY) {
 +                              parent = Z_ARRVAL_P(zv);
 +                      } else {
 +                              phpdbg_error("variable", "type=\"notiterable\" variable=\"%.*s\"", "%.*s is nor an array nor an object", (int) i, input);
 +                              return FAILURE;
 +                      }
 +                      index_len = 0;
 +              }
 +      }
 +
 +      return ret;
 +      error:
 +              phpdbg_error("variable", "type=\"invalidinput\"", "Malformed input");
 +              return FAILURE;
 +}
 +
 +int phpdbg_is_auto_global(char *name, int len) {
++      return zend_is_auto_global_str(name, len);
 +}
 +
 +static int phpdbg_xml_array_element_dump(zval *zv, zend_string *key, zend_ulong num) {
 +      phpdbg_xml("<element");
 +
 +      phpdbg_try_access {
 +              if (key) { /* string key */
 +                      phpdbg_xml(" name=\"%.*s\"", key->len, key->val);
 +              } else { /* numeric key */
 +                      phpdbg_xml(" name=\"%ld\"", num);
 +              }
 +      } phpdbg_catch_access {
 +              phpdbg_xml(" severity=\"error\" ></element>");
 +              return 0;
 +      } phpdbg_end_try_access();
 +
 +      phpdbg_xml(">");
 +
 +      phpdbg_xml_var_dump(zv);
 +
 +      phpdbg_xml("</element>");
 +
 +      return 0;
 +}
 +
 +static int phpdbg_xml_object_property_dump(zval *zv, zend_string *key, zend_ulong num) {
 +      phpdbg_xml("<property");
 +
 +      phpdbg_try_access {
 +              if (key) { /* string key */
 +                      const char *prop_name, *class_name;
 +                      int unmangle = zend_unmangle_property_name(key, &class_name, &prop_name);
 +
 +                      if (class_name && unmangle == SUCCESS) {
 +                              phpdbg_xml(" name=\"%s\"", prop_name);
 +                              if (class_name[0] == '*') {
 +                                      phpdbg_xml(" protection=\"protected\"");
 +                              } else {
 +                                      phpdbg_xml(" class=\"%s\" protection=\"private\"", class_name);
 +                              }
 +                      } else {
 +                              phpdbg_xml(" name=\"%.*s\" protection=\"public\"", key->len, key->val);
 +                      }
 +              } else { /* numeric key */
 +                      phpdbg_xml(" name=\"%ld\" protection=\"public\"", num);
 +              }
 +      } phpdbg_catch_access {
 +              phpdbg_xml(" severity=\"error\" ></property>");
 +              return 0;
 +      } phpdbg_end_try_access();
 +
 +      phpdbg_xml(">");
 +
 +      phpdbg_xml_var_dump(zv);
 +
 +      phpdbg_xml("</property>");
 +
 +      return 0;
 +}
 +
 +#define COMMON (is_ref ? "&" : "")
 +
 +PHPDBG_API void phpdbg_xml_var_dump(zval *zv) {
 +      HashTable *myht;
 +      zend_string *class_name, *key;
 +      zend_ulong num;
 +      zval *val;
 +      int (*element_dump_func)(zval *zv, zend_string *key, zend_ulong num);
 +      zend_bool is_ref = 0;
 +
 +      int is_temp;
 +
 +      phpdbg_try_access {
 +              is_ref = Z_ISREF_P(zv) && GC_REFCOUNT(Z_COUNTED_P(zv)) > 1;
 +              ZVAL_DEREF(zv);
 +
 +              switch (Z_TYPE_P(zv)) {
 +                      case IS_TRUE:
 +                              phpdbg_xml("<bool refstatus=\"%s\" value=\"true\" />", COMMON);
 +                              break;
 +                      case IS_FALSE:
 +                              phpdbg_xml("<bool refstatus=\"%s\" value=\"false\" />", COMMON);
 +                              break;
 +                      case IS_NULL:
 +                              phpdbg_xml("<null refstatus=\"%s\" />", COMMON);
 +                              break;
 +                      case IS_LONG:
 +                              phpdbg_xml("<int refstatus=\"%s\" value=\"" ZEND_LONG_FMT "\" />", COMMON, Z_LVAL_P(zv));
 +                              break;
 +                      case IS_DOUBLE:
 +                              phpdbg_xml("<float refstatus=\"%s\" value=\"%.*G\" />", COMMON, (int) EG(precision), Z_DVAL_P(zv));
 +                              break;
 +                      case IS_STRING:
 +                              phpdbg_xml("<string refstatus=\"%s\" length=\"%d\" value=\"%.*s\" />", COMMON, Z_STRLEN_P(zv), Z_STRLEN_P(zv), Z_STRVAL_P(zv));
 +                              break;
 +                      case IS_ARRAY:
 +                              myht = Z_ARRVAL_P(zv);
 +                              if (ZEND_HASH_APPLY_PROTECTION(myht) && ++myht->u.v.nApplyCount > 1) {
 +                                      phpdbg_xml("<recursion />");
 +                                      --myht->u.v.nApplyCount;
 +                                      break;
 +                              }
 +                              phpdbg_xml("<array refstatus=\"%s\" num=\"%d\">", COMMON, zend_hash_num_elements(myht));
 +                              element_dump_func = phpdbg_xml_array_element_dump;
 +                              is_temp = 0;
 +                              goto head_done;
 +                      case IS_OBJECT:
 +                              myht = Z_OBJDEBUG_P(zv, is_temp);
 +                              if (myht && ++myht->u.v.nApplyCount > 1) {
 +                                      phpdbg_xml("<recursion />");
 +                                      --myht->u.v.nApplyCount;
 +                                      break;
 +                              }
 +
 +                              class_name = Z_OBJ_HANDLER_P(zv, get_class_name)(Z_OBJ_P(zv));
 +                              phpdbg_xml("<object refstatus=\"%s\" class=\"%.*s\" id=\"%d\" num=\"%d\">", COMMON, class_name->len, class_name->val, Z_OBJ_HANDLE_P(zv), myht ? zend_hash_num_elements(myht) : 0);
 +                              zend_string_release(class_name);
 +
 +                              element_dump_func = phpdbg_xml_object_property_dump;
 +head_done:
 +                              if (myht) {
 +                                      ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
 +                                              element_dump_func(val, key, num);
 +                                      } ZEND_HASH_FOREACH_END();
 +                                      zend_hash_apply_with_arguments(myht, (apply_func_args_t) element_dump_func, 0);
 +                                      --myht->u.v.nApplyCount;
 +                                      if (is_temp) {
 +                                              zend_hash_destroy(myht);
 +                                              efree(myht);
 +                                      }
 +                              }
 +                              if (Z_TYPE_P(zv) == IS_ARRAY) {
 +                                      phpdbg_xml("</array>");
 +                              } else {
 +                                      phpdbg_xml("</object>");
 +                              }
 +                              break;
 +                      case IS_RESOURCE: {
 +                              const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(zv));
 +                              phpdbg_xml("<resource refstatus=\"%s\" id=\"%pd\" type=\"%ld\" />", COMMON, Z_RES_P(zv)->handle, type_name ? type_name : "unknown");
 +                              break;
 +                      }
 +                      default:
 +                              break;
 +              }
 +      } phpdbg_end_try_access();
 +}