summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>2000-06-03 01:49:49 +0000
committerZeev Suraski <zeev@php.net>2000-06-03 01:49:49 +0000
commit0b7a9cea8837993d5888c261a7b5200b8a7ab812 (patch)
tree4e28af72b2fc4d28f7dd028f797b801f62de696c /Zend
parent1f6c248909c2fc85398288803fb24e470a4b0193 (diff)
downloadphp-git-0b7a9cea8837993d5888c261a7b5200b8a7ab812.tar.gz
- Fix Win32 compilation (Use winsock2.h from now on)
- Add lambda() support
Diffstat (limited to 'Zend')
-rw-r--r--Zend/ZendTS.dsp6
-rw-r--r--Zend/zend-scanner.l1
-rw-r--r--Zend/zend.c26
-rw-r--r--Zend/zend.h7
-rw-r--r--Zend/zend_builtin_functions.c56
-rw-r--r--Zend/zend_compile.c2
-rw-r--r--Zend/zend_compile.h2
-rw-r--r--Zend/zend_globals.h2
-rw-r--r--Zend/zend_hash.c32
9 files changed, 115 insertions, 19 deletions
diff --git a/Zend/ZendTS.dsp b/Zend/ZendTS.dsp
index 272208d45c..17c5fceebc 100644
--- a/Zend/ZendTS.dsp
+++ b/Zend/ZendTS.dsp
@@ -40,7 +40,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "Release_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDebug_TS" /D "_MBCS" /D "_LIB" /YX /FD /c
-# 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
+# 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
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug_TS"
# ADD RSC /l 0x40d /d "NDebug_TS"
@@ -62,7 +62,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Debug_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_Debug_TS" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# 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
+# 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
# ADD BASE RSC /l 0x40d /d "_Debug_TS"
# ADD RSC /l 0x40d /d "_Debug_TS"
BSC32=bscmake.exe
@@ -84,7 +84,7 @@ LIB32=link.exe -lib
# PROP Target_Dir ""
# 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
# SUBTRACT BASE CPP /YX
-# 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
+# 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
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug_TS"
# ADD RSC /l 0x40d /d "NDebug_TS"
diff --git a/Zend/zend-scanner.l b/Zend/zend-scanner.l
index 3db1f7e96a..4bd51de804 100644
--- a/Zend/zend-scanner.l
+++ b/Zend/zend-scanner.l
@@ -34,7 +34,6 @@
%{
#ifdef ZEND_WIN32
-#include <winsock.h>
#include <io.h>
#endif
diff --git a/Zend/zend.c b/Zend/zend.c
index d1677088a0..07fda8b27c 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -277,6 +277,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals)
zend_copy_constants(executor_globals->zend_constants, global_constants_table);
}
zend_init_rsrc_plist(ELS_C);
+ EG(lambda_count)=0;
}
@@ -594,3 +595,28 @@ ZEND_API void zend_error(int type, const char *format, ...)
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
+}
diff --git a/Zend/zend.h b/Zend/zend.h
index cb9a20b2af..137484f076 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -293,6 +293,13 @@ ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int in
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); }
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 3333530db2..acbd24de91 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -55,6 +55,7 @@ static ZEND_FUNCTION(get_class_methods);
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 };
@@ -93,6 +94,7 @@ static zend_function_entry builtin_functions[] = {
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 }
};
@@ -798,3 +800,57 @@ ZEND_FUNCTION(get_declared_classes)
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
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 2d6b79939e..badb133ad1 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1040,7 +1040,7 @@ void do_return(znode *expr, int do_end_vparse CLS_DC)
}
-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;
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index d3eb8dde58..f7b5128784 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -363,6 +363,8 @@ void do_extended_fcall_end(CLS_D);
void do_ticks(CLS_D);
+void function_add_ref(zend_function *function);
+
#define INITIAL_OP_ARRAY_SIZE 64
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 2c76a8de06..8b5f210538 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -181,6 +181,8 @@ struct _zend_executor_globals {
zval *user_error_handler;
+ int lambda_count;
+
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
#if SUPPORT_INTERACTIVE
int interactive;
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index 7487eebf7c..3566c97ce2 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -78,24 +78,28 @@
}
#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;
@@ -1106,7 +1110,7 @@ void zend_hash_display_pListTail(HashTable *ht)
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;
}
}
@@ -1119,14 +1123,14 @@ void zend_hash_display(HashTable *ht)
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;
}
}