# PROP Intermediate_Dir "Release_TS"\r
# PROP Target_Dir ""\r
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDebug_TS" /D "_MBCS" /D "_LIB" /YX /FD /c\r
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D ZEND_DEBUG=0 /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /D "PHP_WIN32" /FR /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D ZEND_DEBUG=0 /D _WIN32_WINNT=0x400 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /D "PHP_WIN32" /D _WIN32_WINNT=0x0400 /FR /FD /c\r
# SUBTRACT CPP /YX\r
# ADD BASE RSC /l 0x40d /d "NDebug_TS"\r
# ADD RSC /l 0x40d /d "NDebug_TS"\r
# PROP Intermediate_Dir "Debug_TS"\r
# PROP Target_Dir ""\r
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_Debug_TS" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c\r
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_Debug_TS" /D "_LIB" /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D ZEND_DEBUG=1 /D "ZEND_WIN32" /D "ZTS" /D "WIN32" /D "_MBCS" /D "PHP_WIN32" /FR /YX /FD /GZ /c\r
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_Debug_TS" /D ZEND_DEBUG=1 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /D "PHP_WIN32" /D _WIN32_WINNT=0x0400 /FR /YX /FD /GZ /c\r
# ADD BASE RSC /l 0x40d /d "_Debug_TS"\r
# ADD RSC /l 0x40d /d "_Debug_TS"\r
BSC32=bscmake.exe\r
# PROP Target_Dir ""\r
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "WIN32" /D "_MBCS" /D ZEND_DEBUG=0 /FR /FD /c\r
# SUBTRACT BASE CPP /YX\r
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D ZEND_DEBUG=0 /D "ZTS" /D "ZEND_WIN32" /D "ZEND_WIN32_FORCE_INLINE" /D "WIN32" /D "_MBCS" /D "PHP_WIN32" /FR /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D ZEND_DEBUG=0 /D "ZEND_WIN32_FORCE_INLINE" /D _WIN32_WINNT=0x400 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /D "PHP_WIN32" /D _WIN32_WINNT=0x0400 /FR /FD /c\r
# SUBTRACT CPP /YX\r
# ADD BASE RSC /l 0x40d /d "NDebug_TS"\r
# ADD RSC /l 0x40d /d "NDebug_TS"\r
%{
#ifdef ZEND_WIN32
-#include <winsock.h>
#include <io.h>
#endif
zend_copy_constants(executor_globals->zend_constants, global_constants_table);
}
zend_init_rsrc_plist(ELS_C);
+ EG(lambda_count)=0;
}
va_end(args);
}
+
+ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...)
+{
+#if ZEND_DEBUG
+ va_list args;
+
+ va_start(args, format);
+# if ZEND_WIN32
+ {
+ char output_buf[1024];
+
+ vsnprintf(output_buf, 1024, format, args);
+ OutputDebugString(output_buf);
+ OutputDebugString("\n");
+ if (trigger_break && IsDebuggerPresent()) {
+ DebugBreak();
+ }
+ }
+# else
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+# endif
+ va_end(args);
+#endif
+}
ZEND_API void zend_print_zval_r(zval *expr, int indent);
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent);
+ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...);
+#if ZEND_DEBUG
+#define Z_DBG(expr) (expr)
+#else
+#define Z_DBG(expr)
+#endif
+
ZEND_API extern char *empty_string;
#define STR_FREE(ptr) if (ptr && ptr!=empty_string) { efree(ptr); }
static ZEND_FUNCTION(trigger_error);
static ZEND_FUNCTION(set_error_handler);
static ZEND_FUNCTION(get_declared_classes);
+static ZEND_FUNCTION(lambda);
unsigned char first_arg_force_ref[] = { 1, BYREF_FORCE };
unsigned char first_arg_allow_ref[] = { 1, BYREF_ALLOW };
ZEND_FALIAS(user_error, trigger_error, NULL)
ZEND_FE(set_error_handler, NULL)
ZEND_FE(get_declared_classes, NULL)
+ ZEND_FE(lambda, NULL)
{ NULL, NULL, NULL }
};
zend_hash_apply_with_argument(CG(class_table), (apply_func_arg_t)copy_class_name, return_value);
}
/* }}} */
+
+
+#define LAMBDA_TEMP_FUNCNAME "__lambda_func"
+
+/* {{ proto string lambda(string args, string code)
+ Creates an anonymous function, and returns its name (funny, eh?) */
+ZEND_FUNCTION(lambda)
+{
+ char *eval_code, *function_name;
+ int eval_code_length, function_name_length;
+ zval **z_function_args, **z_function_code;
+ int retval;
+ CLS_FETCH();
+
+ if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &z_function_args, &z_function_code)==FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_string_ex(z_function_args);
+ convert_to_string_ex(z_function_code);
+
+ eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME)
+ +Z_STRLEN_PP(z_function_args)
+ +2 /* for the args parentheses */
+ +2 /* for the curly braces */
+ +Z_STRLEN_PP(z_function_code);
+
+ eval_code = (char *) emalloc(eval_code_length);
+ sprintf(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(%s){%s}", Z_STRVAL_PP(z_function_args), Z_STRVAL_PP(z_function_code));
+
+ retval = zend_eval_string(eval_code, NULL CLS_CC ELS_CC);
+ efree(eval_code);
+ if (retval==SUCCESS) {
+ zend_function *func;
+
+ if (zend_hash_find(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **) &func)==FAILURE) {
+ zend_error(E_ERROR, "Unexpected inconsistency in lambda()");
+ RETURN_FALSE;
+ }
+ function_add_ref(func);
+
+ function_name = (char *) emalloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG);
+
+ do {
+ sprintf(function_name, "%clambda_%d", 0, ++EG(lambda_count));
+ function_name_length = strlen(function_name);
+ } while (zend_hash_add(EG(function_table), function_name, function_name_length+1, func, sizeof(zend_function), NULL)==FAILURE);
+ zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
+ RETURN_STRINGL(function_name, function_name_length, 0);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
\ No newline at end of file
}
-static void function_add_ref(zend_function *function)
+void function_add_ref(zend_function *function)
{
if (function->type == ZEND_USER_FUNCTION) {
zend_op_array *op_array = &function->op_array;
void do_ticks(CLS_D);
+void function_add_ref(zend_function *function);
+
#define INITIAL_OP_ARRAY_SIZE 64
zval *user_error_handler;
+ int lambda_count;
+
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
#if SUPPORT_INTERACTIVE
int interactive;
}
#if ZEND_DEBUG
+#define HT_OK 0
#define HT_IS_DESTROYING 1
#define HT_DESTROYED 2
-#define HT_CLEANING 3
-#define HT_OK 0
+#define HT_CLEANING 3
static void _zend_is_inconsistent(HashTable *ht, char *file, int line)
{
+ if (ht->inconsistent==HT_OK) {
+ return;
+ }
switch (ht->inconsistent) {
- case HT_IS_DESTROYING:
- zend_error(E_CORE_ERROR, "ht=%08x is destroying in %s:%d", ht, file, line);
- break;
- case HT_DESTROYED:
- zend_error(E_CORE_ERROR, "ht=%08x is already destroyed in %s:%d", ht, file, line);
- break;
- case HT_CLEANING:
- zend_error(E_CORE_ERROR, "ht=%08x is cleaning %s:%d", ht, file, line);
- break;
+ case HT_IS_DESTROYING:
+ zend_output_debug_string(1, "%s(%d) : ht=0x%08x is being destroyed", file, line, ht);
+ break;
+ case HT_DESTROYED:
+ zend_output_debug_string(1, "%s(%d) : ht=0x%08x is already destroyed", file, line, ht);
+ break;
+ case HT_CLEANING:
+ zend_output_debug_string(1, "%s(%d) : ht=0x%08x is being cleaned", file, line, ht);
+ break;
}
+ zend_bailout();
}
#define IS_CONSISTENT(a) _zend_is_inconsistent(a,__FILE__,__LINE__);
#define SET_INCONSISTENT(n) ht->inconsistent = n;
p = ht->pListTail;
while (p != NULL) {
- zend_printf("pListTail has key %s\n", p->arKey);
+ zend_output_debug_string(0, "pListTail has key %s\n", p->arKey);
p = p->pListLast;
}
}
for (i = 0; i < ht->nTableSize; i++) {
p = ht->arBuckets[i];
while (p != NULL) {
- zend_printf("%s <==> 0x%X\n", p->arKey, p->h);
+ zend_output_debug_string(0, "%s <==> 0x%X\n", p->arKey, p->h);
p = p->pNext;
}
}
p = ht->pListTail;
while (p != NULL) {
- zend_printf("%s <==> 0x%X\n", p->arKey, p->h);
+ zend_output_debug_string(0, "%s <==> 0x%X\n", p->arKey, p->h);
p = p->pListLast;
}
}