ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, char **class_name, zend_class_entry **pce TSRMLS_DC)
{
- zend_string *key = STR_INIT(cur_arg_info->class_name, cur_arg_info->class_name_len, 0);
+ zend_string *key;
+ ALLOCA_FLAG(use_heap);
+
+ STR_ALLOCA_INIT(key, cur_arg_info->class_name, cur_arg_info->class_name_len, use_heap);
*pce = zend_fetch_class(key, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
- STR_FREE(key);
+ STR_ALLOCA_FREE(key, use_heap);
+
*class_name = (*pce) ? (*pce)->name->val : (char*)cur_arg_info->class_name;
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
return "implement interface ";
zval *func;
zend_function *fbc;
zend_string *lc_method_name;
+ ALLOCA_FLAG(use_heap);
if (EXPECTED(key != NULL)) {
lc_method_name = Z_STR_P(key);
} else {
- lc_method_name = STR_ALLOC(method_name->len, 0);
+ STR_ALLOCA_ALLOC(lc_method_name, method_name->len, use_heap);
zend_str_tolower_copy(lc_method_name->val, method_name->val, method_name->len);
}
if (UNEXPECTED((func = zend_hash_find(&zobj->ce->function_table, lc_method_name)) == NULL)) {
if (UNEXPECTED(!key)) {
- STR_FREE(lc_method_name);
+ STR_ALLOCA_FREE(lc_method_name, use_heap);
}
if (zobj->ce->__call) {
return zend_get_user_call_function(zobj->ce, method_name);
}
if (UNEXPECTED(!key)) {
- STR_FREE(lc_method_name);
+ STR_ALLOCA_FREE(lc_method_name, use_heap);
}
return fbc;
}
#define _STR_HEADER_SIZE XtOffsetOf(zend_string, val)
+#define STR_ALLOCA_ALLOC(str, _len, use_heap) do { \
+ (str) = do_alloca(_STR_HEADER_SIZE + (_len) + 1, (use_heap)); \
+ GC_REFCOUNT(str) = 1; \
+ (str)->h = 0; \
+ (str)->len = (_len); \
+} while (0)
+#define STR_ALLOCA_INIT(str, s, len, use_heap) do { \
+ STR_ALLOCA_ALLOC(str, len, use_heap); \
+ memcpy((str)->val, (s), (len)); \
+ (str)->val[(len)] = '\0'; \
+} while (0)
+
+#define STR_ALLOCA_FREE(str, use_heap) free_alloca(str, use_heap)
+
static zend_always_inline zend_ulong zend_str_hash_val(zend_string *s)
{
if (!s->h) {