summaryrefslogtreecommitdiff
path: root/Zend/zend_string.h
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-04-15 21:56:30 +0400
committerDmitry Stogov <dmitry@zend.com>2014-04-15 21:56:30 +0400
commitf9b26bc39a9ea9b1380628eeb0e6dad3c93cfcb0 (patch)
treeda606ba7a4dd4db0119c0f25af9c201eff56eb21 /Zend/zend_string.h
parent61e9b0d265364f9b99a1fdc69a9cafd4d3fc4721 (diff)
downloadphp-git-f9b26bc39a9ea9b1380628eeb0e6dad3c93cfcb0.tar.gz
Cleanup (2-nd round)
Diffstat (limited to 'Zend/zend_string.h')
-rw-r--r--Zend/zend_string.h39
1 files changed, 39 insertions, 0 deletions
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
index 6ff35fb22c..5226c06e79 100644
--- a/Zend/zend_string.h
+++ b/Zend/zend_string.h
@@ -44,10 +44,12 @@ END_EXTERN_C()
#define STR_ADDREF(s) zend_str_addref(s)
#define STR_DELREF(s) zend_str_delref(s)
#define STR_ALLOC(len, persistent) zend_str_alloc(len, persistent)
+#define STR_SAFE_ALLOC(n, m, l, p) zend_str_safe_alloc(n, m, l, p)
#define STR_INIT(str, len, persistent) zend_str_init(str, len, persistent)
#define STR_COPY(s) zend_str_copy(s)
#define STR_DUP(s, persistent) zend_str_dup(s, persistent)
#define STR_REALLOC(s, len, persistent) zend_str_realloc(s, len, persistent)
+#define STR_SAFE_REALLOC(s, n, m, l, p) zend_str_safe_realloc(s, n, m, l, p)
#define STR_FREE(s) zend_str_free(s)
#define STR_RELEASE(s) zend_str_release(s)
#define STR_EMPTY_ALLOC() CG(empty_string)
@@ -107,6 +109,24 @@ static zend_always_inline zend_string *zend_str_alloc(int len, int persistent)
return ret;
}
+static zend_always_inline zend_string *zend_str_safe_alloc(size_t n, size_t m, size_t l, int persistent)
+{
+ zend_string *ret = safe_pemalloc(n, m, sizeof(zend_string) + l - 1, persistent);
+
+ GC_REFCOUNT(ret) = 1;
+#if 1
+ /* optimized single assignment */
+ GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << 8);
+#else
+ GC_TYPE(ret) = IS_STRING;
+ GC_FLAGS(ret) = (persistent ? IS_STR_PERSISTENT : 0);
+ GC_INFO(ret) = 0;
+#endif
+ ret->h = 0;
+ ret->len = (n * m) + l;
+ return ret;
+}
+
static zend_always_inline zend_string *zend_str_init(const char *str, int len, int persistent)
{
zend_string *ret = STR_ALLOC(len, persistent);
@@ -152,6 +172,25 @@ static zend_always_inline zend_string *zend_str_realloc(zend_string *s, int len,
return ret;
}
+static zend_always_inline zend_string *zend_str_safe_realloc(zend_string *s, size_t n, size_t m, size_t l, int persistent)
+{
+ zend_string *ret;
+
+ if (IS_INTERNED(s)) {
+ ret = STR_SAFE_ALLOC(n, m, l, persistent);
+ memcpy(ret->val, s->val, ((n * m) + l > s->len ? s->len : ((n * m) + l)) + 1);
+ } else if (STR_REFCOUNT(s) == 1) {
+ ret = safe_perealloc(s, n, m, sizeof(zend_string) + l - 1, persistent);
+ ret->len = (n * m) + l;
+ STR_FORGET_HASH_VAL(ret);
+ } else {
+ ret = STR_SAFE_ALLOC(n, m, l, persistent);
+ memcpy(ret->val, s->val, ((n * m) + l > s->len ? s->len : ((n * m) + l)) + 1);
+ STR_DELREF(s);
+ }
+ return ret;
+}
+
static zend_always_inline void zend_str_free(zend_string *s)
{
if (!IS_INTERNED(s)) {