summaryrefslogtreecommitdiff
path: root/processor
diff options
context:
space:
mode:
authorXuefer <xuefer@gmail.com>2014-11-08 19:18:37 +0000
committerXuefer <xuefer@gmail.com>2014-11-08 19:18:37 +0000
commiteefebd8773e8f29f5d00f6c03b0b10eb5661f34c (patch)
tree0e82daf35c03e5c58bc206645e79ed72fda07999 /processor
parenta8677af6b70df5a95d4a55c7085c2fc9415f60c0 (diff)
downloadxcache-eefebd8773e8f29f5d00f6c03b0b10eb5661f34c.tar.gz
xcache-eefebd8773e8f29f5d00f6c03b0b10eb5661f34c.zip
split head.m4 into multilpe helper file
git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1554 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
Diffstat (limited to 'processor')
-rw-r--r--processor/class-helper.m4114
-rw-r--r--processor/debug-helper.m498
-rw-r--r--processor/head.m4385
-rw-r--r--processor/string-helper.m479
-rw-r--r--processor/string.m44
-rw-r--r--processor/type-helper.m442
6 files changed, 370 insertions, 352 deletions
diff --git a/processor/class-helper.m4 b/processor/class-helper.m4
new file mode 100644
index 0000000..2e96c3e
--- /dev/null
+++ b/processor/class-helper.m4
@@ -0,0 +1,114 @@
+/* {{{ xc_get_class_num
+ * return class_index + 1
+ */
+static zend_ulong xc_get_class_num(xc_processor_t *processor, zend_class_entry *ce) {
+ zend_uint i;
+ const xc_entry_data_php_t *php = processor->php_src;
+ zend_class_entry *ceptr;
+
+ if (processor->cache_ce == ce) {
+ return processor->cache_class_index + 1;
+ }
+ for (i = 0; i < php->classinfo_cnt; i ++) {
+ ceptr = CestToCePtr(php->classinfos[i].cest);
+ if (ZCEP_REFCOUNT_PTR(ceptr) == ZCEP_REFCOUNT_PTR(ce)) {
+ processor->cache_ce = ceptr;
+ processor->cache_class_index = i;
+ assert(i <= processor->active_class_index);
+ return i + 1;
+ }
+ }
+ assert(0);
+ return (zend_ulong) -1;
+}
+define(`xc_get_class_num', `IFSTORE(``xc_get_class_num'($@)',``xc_get_class_num' can be use in store only')')
+/* }}} */
+#ifdef ZEND_ENGINE_2
+static zend_class_entry *xc_get_class(xc_processor_t *processor, zend_ulong class_num) { /* {{{ */
+ /* must be parent or currrent class */
+ assert(class_num > 0);
+ assert(class_num <= processor->active_class_index + 1);
+ return CestToCePtr(processor->php_dst->classinfos[class_num - 1].cest);
+}
+define(`xc_get_class', `IFRESTORE(``xc_get_class'($@)',``xc_get_class' can be use in restore only')')
+/* }}} */
+#endif
+#ifdef ZEND_ENGINE_2
+/* fix method on store */
+static void xc_fix_method(xc_processor_t *processor, zend_op_array *dst TSRMLS_DC) /* {{{ */
+{
+ zend_function *zf = (zend_function *) dst;
+ zend_class_entry *ce = processor->active_class_entry_dst;
+ const zend_class_entry *srcce = processor->active_class_entry_src;
+
+ /* Fixing up the default functions for objects here since
+ * we need to compare with the newly allocated functions
+ *
+ * caveat: a sub-class method can have the same name as the
+ * parent~s constructor and create problems.
+ */
+
+ if (zf->common.fn_flags & ZEND_ACC_CTOR) {
+ if (!ce->constructor) {
+ ce->constructor = zf;
+ }
+ }
+ else if (zf->common.fn_flags & ZEND_ACC_DTOR) {
+ ce->destructor = zf;
+ }
+ else if (zf->common.fn_flags & ZEND_ACC_CLONE) {
+ ce->clone = zf;
+ }
+ else {
+ pushdef(`SET_IF_SAME_NAMEs', `
+ SET_IF_SAME_NAME(__get);
+ SET_IF_SAME_NAME(__set);
+#ifdef ZEND_ENGINE_2_1
+ SET_IF_SAME_NAME(__unset);
+ SET_IF_SAME_NAME(__isset);
+#endif
+ SET_IF_SAME_NAME(__call);
+#ifdef ZEND_CALLSTATIC_FUNC_NAME
+ SET_IF_SAME_NAME(__callstatic);
+#endif
+#if defined(ZEND_ENGINE_2_2) || PHP_MAJOR_VERSION >= 6
+ SET_IF_SAME_NAME(__tostring);
+#endif
+#if defined(ZEND_ENGINE_2_6)
+ SET_IF_SAME_NAME(__debugInfo);
+#endif
+ ')
+#ifdef IS_UNICODE
+ if (UG(unicode)) {
+#define SET_IF_SAME_NAME(member) \
+ do { \
+ if (srcce->member && u_strcmp(ZSTR_U(zf->common.function_name), ZSTR_U(srcce->member->common.function_name)) == 0) { \
+ ce->member = zf; \
+ } \
+ } \
+ while(0)
+
+ SET_IF_SAME_NAMEs()
+#undef SET_IF_SAME_NAME
+ }
+ else
+#endif
+ do {
+#define SET_IF_SAME_NAME(member) \
+ do { \
+ if (srcce->member && strcmp(ZSTR_S(zf->common.function_name), ZSTR_S(srcce->member->common.function_name)) == 0) { \
+ ce->member = zf; \
+ } \
+ } \
+ while(0)
+
+ SET_IF_SAME_NAMEs()
+#undef SET_IF_SAME_NAME
+ } while (0);
+
+ popdef(`SET_IF_SAME_NAMEs')
+
+ }
+}
+/* }}} */
+#endif
diff --git a/processor/debug-helper.m4 b/processor/debug-helper.m4
new file mode 100644
index 0000000..cca6e69
--- /dev/null
+++ b/processor/debug-helper.m4
@@ -0,0 +1,98 @@
+IFAUTOCHECK(`
+#define RELAYLINE_DC , int relayline
+#define RELAYLINE_CC , __LINE__
+', `
+#define RELAYLINE_DC
+#define RELAYLINE_CC
+')
+
+ifdef(`XCACHE_ENABLE_TEST', `
+#undef NDEBUG
+#include <assert.h>
+m4_errprint(`AUTOCHECK INFO: runtime autocheck Enabled (debug build)')
+', `
+m4_errprint(`AUTOCHECK INFO: runtime autocheck Disabled (optimized build)')
+')
+ifdef(`DEBUG_SIZE', `static int xc_totalsize = 0;')
+
+#ifndef NDEBUG
+# undef inline
+#define inline
+#endif
+
+#ifdef NDEBUG
+ #define notnullable(ptr) (ptr)
+#else
+static inline void *notnullable(const void *ptr)
+{
+ assert(ptr);
+ return (void *) ptr;
+}
+#endif
+
+#ifdef HAVE_XCACHE_DPRINT
+static void xc_dprint_indent(int indent) /* {{{ */
+{
+ int i;
+ for (i = 0; i < indent; i ++) {
+ fprintf(stderr, " ");
+ }
+}
+/* }}} */
+static void xc_dprint_str_len(const char *str, int len) /* {{{ */
+{
+ const unsigned char *p = (const unsigned char *) str;
+ int i;
+ for (i = 0; i < len; i ++) {
+ if (p[i] < 32 || p[i] == 127) {
+ fprintf(stderr, "\\%03o", (unsigned int) p[i]);
+ }
+ else {
+ fputc(p[i], stderr);
+ }
+ }
+}
+/* }}} */
+#endif
+/* {{{ field name checker */
+IFAUTOCHECK(`dnl
+static int xc_check_names(const char *file, int line, const char *functionName, const char **assert_names, size_t assert_names_count, HashTable *done_names)
+{
+ int errors = 0;
+ if (assert_names_count) {
+ size_t i;
+ Bucket *b;
+
+ for (i = 0; i < assert_names_count; ++i) {
+ if (!zend_u_hash_exists(done_names, IS_STRING, assert_names[i], (uint) strlen(assert_names[i]) + 1)) {
+ fprintf(stderr
+ , "Error: missing field at %s `#'%d %s`' : %s\n"
+ , file, line, functionName
+ , assert_names[i]
+ );
+ ++errors;
+ }
+ }
+
+ for (b = done_names->pListHead; b != NULL; b = b->pListNext) {
+ int known = 0;
+ for (i = 0; i < assert_names_count; ++i) {
+ if (strcmp(assert_names[i], BUCKET_KEY_S(b)) == 0) {
+ known = 1;
+ break;
+ }
+ }
+ if (!known) {
+ fprintf(stderr
+ , "Error: unknown field at %s `#'%d %s`' : %s\n"
+ , file, line, functionName
+ , BUCKET_KEY_S(b)
+ );
+ ++errors;
+ }
+ }
+ }
+ return errors;
+}
+')
+/* }}} */
diff --git a/processor/head.m4 b/processor/head.m4
index 36dbddc..ad0b1d3 100644
--- a/processor/head.m4
+++ b/processor/head.m4
@@ -19,85 +19,48 @@ EXPORT(`#include "xcache/xc_allocator.h"')
#include "xcache/xc_utils.h"
#include "util/xc_align.h"
#include "util/xc_trace.h"
+#include "util/xc_util.h"
#include "xcache_globals.h"
#if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT
extern unsigned int zend_hash_canary;
#endif
+dnl }}}
-define(`SIZEOF_zend_uint', `sizeof(zend_uint)')
-define(`COUNTOF_zend_uint', `1')
-define(`SIZEOF_int', `sizeof(int)')
-define(`COUNTOF_int', `1')
-define(`SIZEOF_zend_function', `sizeof(zend_function)')
-define(`COUNTOF_zend_function', `1')
-define(`SIZEOF_zval_ptr', `sizeof(zval_ptr)')
-define(`COUNTOF_zval_ptr', `1')
-define(`SIZEOF_zval_ptr_nullable', `sizeof(zval_ptr_nullable)')
-define(`COUNTOF_zval_ptr_nullable', `1')
-define(`SIZEOF_zend_trait_alias_ptr', `sizeof(zend_trait_alias)')
-define(`COUNTOF_zend_trait_alias_ptr', `1')
-define(`SIZEOF_zend_trait_precedence_ptr', `sizeof(zend_trait_precedence)')
-define(`COUNTOF_zend_trait_precedence_ptr', `1')
-define(`SIZEOF_xc_entry_name_t', `sizeof(xc_entry_name_t)')
-define(`COUNTOF_xc_entry_name_t', `1')
-define(`SIZEOF_xc_ztstring', `sizeof(xc_ztstring)')
-define(`COUNTOF_xc_ztstring', `1')
-
-ifdef(`XCACHE_ENABLE_TEST', `
-#undef NDEBUG
-#include <assert.h>
-m4_errprint(`AUTOCHECK INFO: runtime autocheck Enabled (debug build)')
-', `
-m4_errprint(`AUTOCHECK INFO: runtime autocheck Disabled (optimized build)')
-')
-ifdef(`DEBUG_SIZE', `static int xc_totalsize = 0;')
-
-#ifndef NDEBUG
-# undef inline
-#define inline
-#endif
-
-typedef zval *zval_ptr;
-typedef zval *zval_ptr_nullable;
-typedef char *xc_ztstring;
-#ifdef ZEND_ENGINE_2_4
-typedef zend_trait_alias *zend_trait_alias_ptr;
-typedef zend_trait_precedence *zend_trait_precedence_ptr;
-#endif
-#ifdef ZEND_ENGINE_2_3
-typedef int last_brk_cont_t;
-#else
-typedef zend_uint last_brk_cont_t;
-#endif
-
-typedef zend_uchar xc_zval_type_t;
-typedef int xc_op_type;
-typedef zend_uchar xc_opcode;
-#ifdef IS_UNICODE
-typedef UChar zstr_uchar;
-#endif
-typedef char zstr_char;
-
-#define MAX_DUP_STR_LEN 256
+include(__dir__`/debug-helper.m4')
+include(__dir__`/type-helper.m4')
+include(__dir__`/string-helper.m4')
-#define ptradd(type, ptr, ptrdiff) ((type) (((char *) (ptr)) + (ptrdiff)))
-#define ptrsub(ptr1, ptr2) (((char *) (ptr1)) - ((char *) (ptr2)))
-#ifdef NDEBUG
- #define notnullable(ptr) (ptr)
-#else
-static inline void *notnullable(const void *ptr)
+/* {{{ call op_array ctor handler */
+extern zend_bool xc_have_op_array_ctor;
+static void xc_zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
{
- assert(ptr);
- return (void *) ptr;
+ if (extension->op_array_ctor) {
+ extension->op_array_ctor(op_array);
+ }
}
-#endif
-dnl }}}
+/* }}} */
+/* {{{ memsetptr */
+IFAUTOCHECK(`dnl
+static void *memsetptr(void *mem, void *content, size_t n)
+{
+ void **p = (void **) mem;
+ void **end = (void **) ((char *) mem + n);
+ while (p < end - sizeof(content)) {
+ *p = content;
+ p += sizeof(content);
+ }
+ if (p < end) {
+ memset(p, -1, end - p);
+ }
+ return mem;
+}
+')
+/* }}} */
dnl {{{ _xc_processor_t
typedef struct _xc_processor_t {
char *p;
size_t size;
- HashTable strings;
HashTable zvalptrs;
zend_bool handle_reference; /* enable if to deal with reference */
zend_bool have_references;
@@ -119,290 +82,12 @@ typedef struct _xc_processor_t {
const xc_op_array_info_t *active_op_array_infos_src;
zend_bool readonly_protection; /* wheather it's present */
-IFAUTOCHECK(xc_vector_t allocsizes;)
-} xc_processor_t;
-dnl }}}
-EXPORT(`typedef struct _xc_dasm_t { const zend_op_array *active_op_array_src; } xc_dasm_t;')
-/* {{{ memsetptr */
-IFAUTOCHECK(`dnl
-static void *memsetptr(void *mem, void *content, size_t n)
-{
- void **p = (void **) mem;
- void **end = (void **) ((char *) mem + n);
- while (p < end - sizeof(content)) {
- *p = content;
- p += sizeof(content);
- }
- if (p < end) {
- memset(p, -1, end - p);
- }
- return mem;
-}
-')
-/* }}} */
-#ifdef HAVE_XCACHE_DPRINT
-static void xc_dprint_indent(int indent) /* {{{ */
-{
- int i;
- for (i = 0; i < indent; i ++) {
- fprintf(stderr, " ");
- }
-}
-/* }}} */
-static void xc_dprint_str_len(const char *str, int len) /* {{{ */
-{
- const unsigned char *p = (const unsigned char *) str;
- int i;
- for (i = 0; i < len; i ++) {
- if (p[i] < 32 || p[i] == 127) {
- fprintf(stderr, "\\%03o", (unsigned int) p[i]);
- }
- else {
- fputc(p[i], stderr);
- }
- }
-}
-/* }}} */
-#endif
-static inline size_t xc_zstrlen_char(const_zstr s) /* {{{ */
-{
- return strlen(ZSTR_S(s));
-}
-/* }}} */
-#ifdef IS_UNICODE
-static inline size_t xc_zstrlen_uchar(zstr s) /* {{{ */
-{
- return u_strlen(ZSTR_U(s));
-}
-/* }}} */
-static inline size_t xc_zstrlen(int type, const_zstr s) /* {{{ */
-{
- return type == IS_UNICODE ? xc_zstrlen_uchar(s) : xc_zstrlen_char(s);
-}
-/* }}} */
-#else
-/* {{{ xc_zstrlen */
-#define xc_zstrlen(dummy, s) xc_zstrlen_char(s)
-/* }}} */
-#endif
-#undef C_RELAYLINE
-#define C_RELAYLINE
-IFAUTOCHECK(`
-#undef C_RELAYLINE
-#define C_RELAYLINE , __LINE__
-')
-static inline void xc_calc_string_n(xc_processor_t *processor, zend_uchar type, const_zstr str, long size IFAUTOCHECK(`, int relayline') TSRMLS_DC) { /* {{{ */
- pushdef(`PROCESSOR_TYPE', `calc')
- pushdef(`__LINE__', `relayline')
- size_t realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
- long dummy = 1;
-
- if (realsize > MAX_DUP_STR_LEN) {
- ALLOC(, char, realsize)
- }
- else if (zend_u_hash_add(&processor->strings, type, str, (uint) size, (void *) &dummy, sizeof(dummy), NULL) == SUCCESS) {
- /* new string */
- ALLOC(, char, realsize)
- }
- IFAUTOCHECK(`
- else {
- dnl fprintf(stderr, "dupstr %s\n", ZSTR_S(str));
- }
- ')
- popdef(`__LINE__')
- popdef(`PROCESSOR_TYPE')
-}
-/* }}} */
-static inline zstr xc_store_string_n(xc_processor_t *processor, zend_uchar type, const_zstr str, long size IFAUTOCHECK(`, int relayline')) { /* {{{ */
- pushdef(`PROCESSOR_TYPE', `store')
- pushdef(`__LINE__', `relayline')
- size_t realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
- zstr ret, *pret;
-
- if (realsize > MAX_DUP_STR_LEN) {
- ALLOC(ZSTR_V(ret), char, realsize)
- memcpy(ZSTR_V(ret), ZSTR_V(str), realsize);
- return ret;
- }
-
- if (zend_u_hash_find(&processor->strings, type, str, (uint) size, (void **) &pret) == SUCCESS) {
- TRACE("found old string %s:%ld %p", str, size, *pret);
- return *pret;
- }
-
- /* new string */
- ALLOC(ZSTR_V(ret), char, realsize)
- memcpy(ZSTR_V(ret), ZSTR_V(str), realsize);
- zend_u_hash_add(&processor->strings, type, str, (uint) size, (void *) &ret, sizeof(zstr), NULL);
- TRACE("stored new string %s:%ld %p", str, size, ret);
- return ret;
-
- popdef(`__LINE__')
- popdef(`PROCESSOR_TYPE')
-}
-/* }}} */
-/* {{{ xc_get_class_num
- * return class_index + 1
- */
-static zend_ulong xc_get_class_num(xc_processor_t *processor, zend_class_entry *ce) {
- zend_uint i;
- const xc_entry_data_php_t *php = processor->php_src;
- zend_class_entry *ceptr;
-
- if (processor->cache_ce == ce) {
- return processor->cache_class_index + 1;
- }
- for (i = 0; i < php->classinfo_cnt; i ++) {
- ceptr = CestToCePtr(php->classinfos[i].cest);
- if (ZCEP_REFCOUNT_PTR(ceptr) == ZCEP_REFCOUNT_PTR(ce)) {
- processor->cache_ce = ceptr;
- processor->cache_class_index = i;
- assert(i <= processor->active_class_index);
- return i + 1;
- }
- }
- assert(0);
- return (zend_ulong) -1;
-}
-define(`xc_get_class_num', `IFSTORE(``xc_get_class_num'($@)',``xc_get_class_num' can be use in store only')')
-/* }}} */
-#ifdef ZEND_ENGINE_2
-static zend_class_entry *xc_get_class(xc_processor_t *processor, zend_ulong class_num) { /* {{{ */
- /* must be parent or currrent class */
- assert(class_num > 0);
- assert(class_num <= processor->active_class_index + 1);
- return CestToCePtr(processor->php_dst->classinfos[class_num - 1].cest);
-}
-define(`xc_get_class', `IFRESTORE(``xc_get_class'($@)',``xc_get_class' can be use in restore only')')
-/* }}} */
-#endif
-#ifdef ZEND_ENGINE_2
-/* fix method on store */
-static void xc_fix_method(xc_processor_t *processor, zend_op_array *dst TSRMLS_DC) /* {{{ */
-{
- zend_function *zf = (zend_function *) dst;
- zend_class_entry *ce = processor->active_class_entry_dst;
- const zend_class_entry *srcce = processor->active_class_entry_src;
-
- /* Fixing up the default functions for objects here since
- * we need to compare with the newly allocated functions
- *
- * caveat: a sub-class method can have the same name as the
- * parent~s constructor and create problems.
- */
- if (zf->common.fn_flags & ZEND_ACC_CTOR) {
- if (!ce->constructor) {
- ce->constructor = zf;
- }
- }
- else if (zf->common.fn_flags & ZEND_ACC_DTOR) {
- ce->destructor = zf;
- }
- else if (zf->common.fn_flags & ZEND_ACC_CLONE) {
- ce->clone = zf;
- }
- else {
- pushdef(`SET_IF_SAME_NAMEs', `
- SET_IF_SAME_NAME(__get);
- SET_IF_SAME_NAME(__set);
-#ifdef ZEND_ENGINE_2_1
- SET_IF_SAME_NAME(__unset);
- SET_IF_SAME_NAME(__isset);
-#endif
- SET_IF_SAME_NAME(__call);
-#ifdef ZEND_CALLSTATIC_FUNC_NAME
- SET_IF_SAME_NAME(__callstatic);
-#endif
-#if defined(ZEND_ENGINE_2_2) || PHP_MAJOR_VERSION >= 6
- SET_IF_SAME_NAME(__tostring);
-#endif
-#if defined(ZEND_ENGINE_2_6)
- SET_IF_SAME_NAME(__debugInfo);
-#endif
- ')
-#ifdef IS_UNICODE
- if (UG(unicode)) {
-#define SET_IF_SAME_NAME(member) \
- do { \
- if (srcce->member && u_strcmp(ZSTR_U(zf->common.function_name), ZSTR_U(srcce->member->common.function_name)) == 0) { \
- ce->member = zf; \
- } \
- } \
- while(0)
-
- SET_IF_SAME_NAMEs()
-#undef SET_IF_SAME_NAME
- }
- else
-#endif
- do {
-#define SET_IF_SAME_NAME(member) \
- do { \
- if (srcce->member && strcmp(ZSTR_S(zf->common.function_name), ZSTR_S(srcce->member->common.function_name)) == 0) { \
- ce->member = zf; \
- } \
- } \
- while(0)
+ STRING_HELPER_T
- SET_IF_SAME_NAMEs()
-#undef SET_IF_SAME_NAME
- } while (0);
-
- popdef(`SET_IF_SAME_NAMEs')
-
- }
-}
-/* }}} */
-#endif
-/* {{{ call op_array ctor handler */
-extern zend_bool xc_have_op_array_ctor;
-static void xc_zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
-{
- if (extension->op_array_ctor) {
- extension->op_array_ctor(op_array);
- }
-}
-/* }}} */
-/* {{{ field name checker */
-IFAUTOCHECK(`dnl
-static int xc_check_names(const char *file, int line, const char *functionName, const char **assert_names, size_t assert_names_count, HashTable *done_names)
-{
- int errors = 0;
- if (assert_names_count) {
- size_t i;
- Bucket *b;
-
- for (i = 0; i < assert_names_count; ++i) {
- if (!zend_u_hash_exists(done_names, IS_STRING, assert_names[i], (uint) strlen(assert_names[i]) + 1)) {
- fprintf(stderr
- , "Error: missing field at %s `#'%d %s`' : %s\n"
- , file, line, functionName
- , assert_names[i]
- );
- ++errors;
- }
- }
+ IFAUTOCHECK(xc_vector_t allocsizes;)
+} xc_processor_t;
+dnl }}}
+STRING_HELPERS()
- for (b = done_names->pListHead; b != NULL; b = b->pListNext) {
- int known = 0;
- for (i = 0; i < assert_names_count; ++i) {
- if (strcmp(assert_names[i], BUCKET_KEY_S(b)) == 0) {
- known = 1;
- break;
- }
- }
- if (!known) {
- fprintf(stderr
- , "Error: unknown field at %s `#'%d %s`' : %s\n"
- , file, line, functionName
- , BUCKET_KEY_S(b)
- );
- ++errors;
- }
- }
- }
- return errors;
-}
-')
-/* }}} */
+include(__dir__`/class-helper.m4')
diff --git a/processor/string-helper.m4 b/processor/string-helper.m4
new file mode 100644
index 0000000..d559ffb
--- /dev/null
+++ b/processor/string-helper.m4
@@ -0,0 +1,79 @@
+#define MAX_DUP_STR_LEN 256
+
+define(`STRING_HELPER_T', `
+HashTable strings;
+')
+
+define(`STRING_HELPERS', `
+static inline size_t xc_zstrlen_char(const_zstr s) /* {{{ */
+{
+ return strlen(ZSTR_S(s));
+}
+/* }}} */
+#ifdef IS_UNICODE
+static inline size_t xc_zstrlen_uchar(zstr s) /* {{{ */
+{
+ return u_strlen(ZSTR_U(s));
+}
+/* }}} */
+static inline size_t xc_zstrlen(int type, const_zstr s) /* {{{ */
+{
+ return type == IS_UNICODE ? xc_zstrlen_uchar(s) : xc_zstrlen_char(s);
+}
+/* }}} */
+#else
+/* {{{ xc_zstrlen */
+#define xc_zstrlen(dummy, s) xc_zstrlen_char(s)
+/* }}} */
+#endif
+static inline void xc_calc_string_n(xc_processor_t *processor, zend_uchar type, const_zstr str, long size RELAYLINE_DC TSRMLS_DC) { /* {{{ */
+ pushdef(`PROCESSOR_TYPE', `calc')
+ pushdef(`__LINE__', `relayline')
+ size_t realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
+ long dummy = 1;
+
+ if (realsize > MAX_DUP_STR_LEN) {
+ ALLOC(, char, realsize)
+ }
+ else if (zend_u_hash_add(&processor->strings, type, str, (uint) size, (void *) &dummy, sizeof(dummy), NULL) == SUCCESS) {
+ /* new string */
+ ALLOC(, char, realsize)
+ }
+ IFAUTOCHECK(`
+ else {
+ dnl fprintf(stderr, "dupstr %s\n", ZSTR_S(str));
+ }
+ ')
+ popdef(`__LINE__')
+ popdef(`PROCESSOR_TYPE')
+}
+/* }}} */
+static inline zstr xc_store_string_n(xc_processor_t *processor, zend_uchar type, const_zstr str, long size RELAYLINE_DC) { /* {{{ */
+ pushdef(`PROCESSOR_TYPE', `store')
+ pushdef(`__LINE__', `relayline')
+ size_t realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
+ zstr ret, *pret;
+
+ if (realsize > MAX_DUP_STR_LEN) {
+ ALLOC(ZSTR_V(ret), char, realsize)
+ memcpy(ZSTR_V(ret), ZSTR_V(str), realsize);
+ return ret;
+ }
+
+ if (zend_u_hash_find(&processor->strings, type, str, (uint) size, (void **) &pret) == SUCCESS) {
+ TRACE("found old string %s:%ld %p", str, size, *pret);
+ return *pret;
+ }
+
+ /* new string */
+ ALLOC(ZSTR_V(ret), char, realsize)
+ memcpy(ZSTR_V(ret), ZSTR_V(str), realsize);
+ zend_u_hash_add(&processor->strings, type, str, (uint) size, (void *) &ret, sizeof(zstr), NULL);
+ TRACE("stored new string %s:%ld %p", str, size, ret);
+ return ret;
+
+ popdef(`__LINE__')
+ popdef(`PROCESSOR_TYPE')
+}
+/* }}} */
+')
diff --git a/processor/string.m4 b/processor/string.m4
index 5b1f592..39eba21 100644
--- a/processor/string.m4
+++ b/processor/string.m4
@@ -58,8 +58,8 @@ define(`PROC_STRING_N_EX', `
fprintf(stderr, "\" len=%lu\n", (unsigned long) $3 - 1);
')
')
- IFCALC(`xc_calc_string_n(processor, ISTYPE, SRCSTR, $3 C_RELAYLINE TSRMLS_CC);')
- IFSTORE(`DSTPTR = ifdef(`REALPTRTYPE', `(REALPTRTYPE() *)') ifelse(PTRTYPE,`char',`ZSTR_S',`ZSTR_U')(xc_store_string_n(processor, ISTYPE, SRCSTR, $3 C_RELAYLINE));')
+ IFCALC(`xc_calc_string_n(processor, ISTYPE, SRCSTR, $3 RELAYLINE_CC TSRMLS_CC);')
+ IFSTORE(`DSTPTR = ifdef(`REALPTRTYPE', `(REALPTRTYPE() *)') ifelse(PTRTYPE,`char',`ZSTR_S',`ZSTR_U')(xc_store_string_n(processor, ISTYPE, SRCSTR, $3 RELAYLINE_CC));')
IFRESTORE(`
DSTPTR = ifdef(`REALPTRTYPE', `(REALPTRTYPE() *)') STRDUP() (SRCPTR, ($3) - 1);
')
diff --git a/processor/type-helper.m4 b/processor/type-helper.m4
new file mode 100644
index 0000000..98b1316
--- /dev/null
+++ b/processor/type-helper.m4
@@ -0,0 +1,42 @@
+define(`SIZEOF_zend_uint', `sizeof(zend_uint)')
+define(`COUNTOF_zend_uint', `1')
+define(`SIZEOF_int', `sizeof(int)')
+define(`COUNTOF_int', `1')
+define(`SIZEOF_zend_function', `sizeof(zend_function)')
+define(`COUNTOF_zend_function', `1')
+define(`SIZEOF_zval_ptr', `sizeof(zval_ptr)')
+define(`COUNTOF_zval_ptr', `1')
+define(`SIZEOF_zval_ptr_nullable', `sizeof(zval_ptr_nullable)')
+define(`COUNTOF_zval_ptr_nullable', `1')
+define(`SIZEOF_zend_trait_alias_ptr', `sizeof(zend_trait_alias)')
+define(`COUNTOF_zend_trait_alias_ptr', `1')
+define(`SIZEOF_zend_trait_precedence_ptr', `sizeof(zend_trait_precedence)')
+define(`COUNTOF_zend_trait_precedence_ptr', `1')
+define(`SIZEOF_xc_entry_name_t', `sizeof(xc_entry_name_t)')
+define(`COUNTOF_xc_entry_name_t', `1')
+define(`SIZEOF_xc_ztstring', `sizeof(xc_ztstring)')
+define(`COUNTOF_xc_ztstring', `1')
+
+typedef zval *zval_ptr;
+typedef zval *zval_ptr_nullable;
+typedef char *xc_ztstring;
+#ifdef ZEND_ENGINE_2_4
+typedef zend_trait_alias *zend_trait_alias_ptr;
+typedef zend_trait_precedence *zend_trait_precedence_ptr;
+#endif
+#ifdef ZEND_ENGINE_2_3
+typedef int last_brk_cont_t;
+#else
+typedef zend_uint last_brk_cont_t;
+#endif
+
+typedef zend_uchar xc_zval_type_t;
+typedef int xc_op_type;
+typedef zend_uchar xc_opcode;
+#ifdef IS_UNICODE
+typedef UChar zstr_uchar;
+#endif
+typedef char zstr_char;
+
+EXPORT(`typedef struct _xc_dasm_t { const zend_op_array *active_op_array_src; } xc_dasm_t;')
+