Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add optional support for C0x inline semantics.

These are enabled by specifying `--enable-c0x-inline' on the command
line. We might add an autoconf check for this particular feature
later.
  • Loading branch information...
commit df74f1dfabafb515bdf8ffee5f989761c0d6604d 1 parent 307a234
Sascha Schumann authored
View
8 Zend/Makefile.am
@@ -3,12 +3,14 @@
#CLEANFILES = zend-parser.c zend-parser.h zend-scanner.c zend-parser.output
AUTOMAKE_OPTIONS=foreign
-EXTRA_LTLIBRARIES=libZend_cc.la libZend_c.la
-noinst_LTLIBRARIES=$(ZEND_SCANNER) libZend.la
+EXTRA_LTLIBRARIES=libZend_cc.la libZend_c.la libZend_gcc.la
+noinst_LTLIBRARIES=$(ZEND_SCANNER) $(ZEND_GCC) libZend.la
libZend_cc_la_SOURCES=zend-scanner-cc.cc
libZend_c_la_SOURCES=zend-scanner.c
+libZend_gcc_la_SOURCES=zend_gcc_inline.c
+
libZend_la_SOURCES=\
zend-parser.y \
zend_alloc.c zend_compile.c zend_constants.c zend_dynamic_array.c \
@@ -17,7 +19,7 @@ libZend_la_SOURCES=\
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c
-libZend_la_LIBADD = $(ZEND_SCANNER)
+libZend_la_LIBADD = $(ZEND_SCANNER) $(ZEND_GCC)
libZend_la_LDFLAGS = @EXTRA_LIBS@
libZend_la_DEPENDENCIES = $(ZEND_SCANNER)
View
17 Zend/Zend.m4
@@ -100,6 +100,13 @@ AC_ARG_ENABLE(debug,
AC_DEFUN(LIBZEND_OTHER_CHECKS,[
+AC_ARG_ENABLE(c0x-inline,
+[ --enable-c0x-inline Enable C0x-inline semantics],[
+ ZEND_C0X_INLINE=$enableval
+],[
+ ZEND_C0X_INLINE=no
+])
+
AC_ARG_ENABLE(experimental-zts,
[ --enable-experimental-zts This will most likely break your build],[
ZEND_EXPERIMENTAL_ZTS=$enableval
@@ -122,6 +129,9 @@ AC_ARG_ENABLE(memory-limit,
ZEND_MEMORY_LIMIT=no
])
+AC_MSG_CHECKING(whether to enable C0x-inline semantics)
+AC_MSG_RESULT($ZEND_C0X_INLINE)
+
AC_MSG_CHECKING(whether to enable experimental ZTS)
AC_MSG_RESULT($ZEND_EXPERIMENTAL_ZTS)
@@ -155,6 +165,13 @@ else
ZEND_SCANNER_TYPE=c
fi
+if test "$ZEND_C0X_INLINE" = "yes"; then
+ AC_DEFINE(C0X_INLINE_SEMANTICS, 1, [whether to enable C0x-inline semantics])
+else
+ ZEND_GCC=libZend_gcc.la
+ AC_SUBST(ZEND_GCC)
+fi
+
ZEND_SCANNER="libZend_${ZEND_SCANNER_TYPE}.la"
if test "$ZEND_MEMORY_LIMIT" = "yes"; then
View
1  Zend/zend_API.h
@@ -26,6 +26,7 @@
#include "zend_fast_cache.h"
#include "zend_operators.h"
#include "zend_variables.h"
+#include "zend_execute.h"
#define ZEND_FN(name) zend_if_##name
#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
View
3  Zend/zend_compile.h
@@ -191,7 +191,6 @@ typedef struct _zend_file_handle {
} zend_file_handle;
-#include "zend_globals.h"
#define IS_CONST (1<<0)
#define IS_TMP_VAR (1<<1)
@@ -201,6 +200,8 @@ typedef struct _zend_file_handle {
#define EXT_TYPE_UNUSED (1<<0)
+#include "zend_globals.h"
+
BEGIN_EXTERN_C()
void init_compiler(CLS_D ELS_DC);
View
146 Zend/zend_execute.h
@@ -23,6 +23,8 @@
#include "zend_compile.h"
#include "zend_hash.h"
+#include "zend_variables.h"
+#include "zend_execute_locks.h"
typedef union _temp_variable {
zval tmp_var;
@@ -52,15 +54,95 @@ void init_executor(CLS_D ELS_DC);
void shutdown_executor(ELS_D);
void execute(zend_op_array *op_array ELS_DC);
ZEND_API int zend_is_true(zval *op);
-ZEND_API inline void safe_free_zval_ptr(zval *p);
+ZEND_API inline void safe_free_zval_ptr(zval *p)
+#if defined(C0X_INLINE_SEMANTICS)
+{
+ ELS_FETCH();
+
+ if (p!=EG(uninitialized_zval_ptr)) {
+ FREE_ZVAL(p);
+ }
+}
+#else
+;
+#endif
+
ZEND_API int zend_eval_string(char *str, zval *retval_ptr CLS_DC ELS_DC);
-ZEND_API inline int i_zend_is_true(zval *op);
+ZEND_API inline int i_zend_is_true(zval *op)
+#if defined(C0X_INLINE_SEMANTICS)
+{
+ int result;
+
+ switch (op->type) {
+ case IS_NULL:
+ result = 0;
+ break;
+ case IS_LONG:
+ case IS_BOOL:
+ case IS_RESOURCE:
+ result = (op->value.lval?1:0);
+ break;
+ case IS_DOUBLE:
+ result = (op->value.dval ? 1 : 0);
+ break;
+ case IS_STRING:
+ if (op->value.str.len == 0
+ || (op->value.str.len==1 && op->value.str.val[0]=='0')) {
+ result = 0;
+ } else {
+ result = 1;
+ }
+ break;
+ case IS_ARRAY:
+ result = (zend_hash_num_elements(op->value.ht)?1:0);
+ break;
+ case IS_OBJECT:
+ result = (zend_hash_num_elements(op->value.obj.properties)?1:0);
+ break;
+ default:
+ result = 0;
+ break;
+ }
+ return result;
+}
+#else
+;
+#endif
+
ZEND_API int zval_update_constant(zval **pp, void *arg);
-ZEND_API inline void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts ELS_DC);
/* dedicated Zend executor functions - do not use! */
-ZEND_API inline void zend_ptr_stack_clear_multiple(ELS_D);
-ZEND_API inline int zend_ptr_stack_get_arg(int requested_arg, void **data ELS_DC);
+ZEND_API inline void zend_ptr_stack_clear_multiple(ELS_D)
+#if defined(C0X_INLINE_SEMANTICS)
+{
+ void **p = EG(argument_stack).top_element-2;
+ int delete_count = (ulong) *p;
+
+ EG(argument_stack).top -= (delete_count+2);
+ while (--delete_count>=0) {
+ zval_ptr_dtor((zval **) --p);
+ }
+ EG(argument_stack).top_element = p;
+}
+#else
+;
+#endif
+
+ZEND_API inline int zend_ptr_stack_get_arg(int requested_arg, void **data ELS_DC)
+#if defined(C0X_INLINE_SEMANTICS)
+{
+ void **p = EG(argument_stack).top_element-2;
+ int arg_count = (ulong) *p;
+
+ if (requested_arg>arg_count) {
+ return FAILURE;
+ }
+ *data = (p-arg_count+requested_arg-1);
+ return SUCCESS;
+}
+#else
+;
+#endif
#if SUPPORT_INTERACTIVE
void execute_new_code(CLS_D);
@@ -78,6 +160,60 @@ ZEND_API zend_bool zend_is_executing(void);
#define active_opline (*EG(opline_ptr))
+ZEND_API inline void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts ELS_DC)
+#if defined(C0X_INLINE_SEMANTICS)
+{
+ zval *variable_ptr = *variable_ptr_ptr;
+ zval *value_ptr;
+
+
+ if (!value_ptr_ptr) {
+ zend_error(E_ERROR, "Cannot create references to string offsets nor overloaded objects");
+ return;
+ }
+
+ value_ptr = *value_ptr_ptr;
+ if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) {
+ variable_ptr_ptr = &EG(uninitialized_zval_ptr);
+/* } else if (variable_ptr==&EG(uninitialized_zval) || variable_ptr!=value_ptr) { */
+ } else if (variable_ptr_ptr != value_ptr_ptr) {
+ variable_ptr->refcount--;
+ if (variable_ptr->refcount==0) {
+ zendi_zval_dtor(*variable_ptr);
+ FREE_ZVAL(variable_ptr);
+ }
+
+ if (!PZVAL_IS_REF(value_ptr)) {
+ /* break it away */
+ value_ptr->refcount--;
+ if (value_ptr->refcount>0) {
+ ALLOC_ZVAL(*value_ptr_ptr);
+ **value_ptr_ptr = *value_ptr;
+ value_ptr = *value_ptr_ptr;
+ zendi_zval_copy_ctor(*value_ptr);
+ }
+ value_ptr->refcount = 1;
+ value_ptr->is_ref = 1;
+ }
+
+ *variable_ptr_ptr = value_ptr;
+ value_ptr->refcount++;
+ } else {
+ if (variable_ptr->refcount>1) { /* we need to break away */
+ SEPARATE_ZVAL(variable_ptr_ptr);
+ }
+ (*variable_ptr_ptr)->is_ref = 1;
+ }
+
+ if (result && (result->op_type != IS_UNUSED)) {
+ Ts[result->u.var].var.ptr_ptr = variable_ptr_ptr;
+ SELECTIVE_PZVAL_LOCK(*variable_ptr_ptr, result);
+ AI_USE_PTR(Ts[result->u.var].var);
+ }
+}
+#else
+;
+#endif
#define IS_OVERLOADED_OBJECT 1
#define IS_STRING_OFFSET 2
View
128 Zend/zend_execute_API.c
@@ -237,16 +237,6 @@ ZEND_API zend_bool zend_is_executing()
}
-ZEND_API inline void safe_free_zval_ptr(zval *p)
-{
- ELS_FETCH();
-
- if (p!=EG(uninitialized_zval_ptr)) {
- FREE_ZVAL(p);
- }
-}
-
-
ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC)
{
#if DEBUG_ZEND>=2
@@ -262,44 +252,6 @@ ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC)
}
-ZEND_API inline int i_zend_is_true(zval *op)
-{
- int result;
-
- switch (op->type) {
- case IS_NULL:
- result = 0;
- break;
- case IS_LONG:
- case IS_BOOL:
- case IS_RESOURCE:
- result = (op->value.lval?1:0);
- break;
- case IS_DOUBLE:
- result = (op->value.dval ? 1 : 0);
- break;
- case IS_STRING:
- if (op->value.str.len == 0
- || (op->value.str.len==1 && op->value.str.val[0]=='0')) {
- result = 0;
- } else {
- result = 1;
- }
- break;
- case IS_ARRAY:
- result = (zend_hash_num_elements(op->value.ht)?1:0);
- break;
- case IS_OBJECT:
- result = (zend_hash_num_elements(op->value.obj.properties)?1:0);
- break;
- default:
- result = 0;
- break;
- }
- return result;
-}
-
-
ZEND_API int zend_is_true(zval *op)
{
return i_zend_is_true(op);
@@ -550,57 +502,6 @@ ZEND_API int zend_eval_string(char *str, zval *retval_ptr CLS_DC ELS_DC)
}
-ZEND_API inline void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts ELS_DC)
-{
- zval *variable_ptr = *variable_ptr_ptr;
- zval *value_ptr;
-
-
- if (!value_ptr_ptr) {
- zend_error(E_ERROR, "Cannot create references to string offsets nor overloaded objects");
- return;
- }
-
- value_ptr = *value_ptr_ptr;
- if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) {
- variable_ptr_ptr = &EG(uninitialized_zval_ptr);
-/* } else if (variable_ptr==&EG(uninitialized_zval) || variable_ptr!=value_ptr) { */
- } else if (variable_ptr_ptr != value_ptr_ptr) {
- variable_ptr->refcount--;
- if (variable_ptr->refcount==0) {
- zendi_zval_dtor(*variable_ptr);
- FREE_ZVAL(variable_ptr);
- }
-
- if (!PZVAL_IS_REF(value_ptr)) {
- /* break it away */
- value_ptr->refcount--;
- if (value_ptr->refcount>0) {
- ALLOC_ZVAL(*value_ptr_ptr);
- **value_ptr_ptr = *value_ptr;
- value_ptr = *value_ptr_ptr;
- zendi_zval_copy_ctor(*value_ptr);
- }
- value_ptr->refcount = 1;
- value_ptr->is_ref = 1;
- }
-
- *variable_ptr_ptr = value_ptr;
- value_ptr->refcount++;
- } else {
- if (variable_ptr->refcount>1) { /* we need to break away */
- SEPARATE_ZVAL(variable_ptr_ptr);
- }
- (*variable_ptr_ptr)->is_ref = 1;
- }
-
- if (result && (result->op_type != IS_UNUSED)) {
- Ts[result->u.var].var.ptr_ptr = variable_ptr_ptr;
- SELECTIVE_PZVAL_LOCK(*variable_ptr_ptr, result);
- AI_USE_PTR(Ts[result->u.var].var);
- }
-}
-
#if SUPPORT_INTERACTIVE
void execute_new_code(CLS_D)
@@ -622,32 +523,3 @@ void execute_new_code(CLS_D)
#endif
-/* these are a dedicated, optimized, function, and shouldn't be used for any purpose
- * other than by Zend's executor
- */
-ZEND_API inline void zend_ptr_stack_clear_multiple(ELS_D)
-{
- void **p = EG(argument_stack).top_element-2;
- int delete_count = (ulong) *p;
-
- EG(argument_stack).top -= (delete_count+2);
- while (--delete_count>=0) {
- zval_ptr_dtor((zval **) --p);
- }
- EG(argument_stack).top_element = p;
-}
-
-
-
-ZEND_API int zend_ptr_stack_get_arg(int requested_arg, void **data ELS_DC)
-{
- void **p = EG(argument_stack).top_element-2;
- int arg_count = (ulong) *p;
-
- if (requested_arg>arg_count) {
- return FAILURE;
- }
- *data = (p-arg_count+requested_arg-1);
- return SUCCESS;
-}
-
View
7 Zend/zend_gcc_inline.c
@@ -0,0 +1,7 @@
+
+#define C0X_INLINE_SEMANTICS
+
+#include "zend.h"
+
+#include "zend_execute.h"
+#include "zend_operators.h"
View
2  Zend/zend_globals.h
@@ -54,7 +54,6 @@ END_EXTERN_C()
#include "zend_compile.h"
-#include "zend_execute.h"
/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table
@@ -209,5 +208,4 @@ struct _zend_alloc_globals {
#endif
};
-
#endif /* _T_GLOBALS_H */
View
60 Zend/zend_operators.c
@@ -1589,65 +1589,7 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2)
* returns FLAG_IS_BC if the number might lose accuracy when converted to a double
*/
-#if 1
-ZEND_API inline int is_numeric_string(char *str, int length, long *lval, double *dval)
-{
- long local_lval;
- double local_dval;
- char *end_ptr;
-
- if (!length) {
- return 0;
- }
-
- errno=0;
- local_lval = strtol(str, &end_ptr, 10);
- if (errno!=ERANGE && end_ptr == str+length) { /* integer string */
- if (lval) {
- *lval = local_lval;
- }
- return IS_LONG;
- }
-
- errno=0;
- local_dval = strtod(str, &end_ptr);
- if (errno!=ERANGE && end_ptr == str+length) { /* floating point string */
- if (! finite(local_dval)) {
- /* "inf","nan" and maybe other weird ones */
- return 0;
- }
-
- if (dval) {
- *dval = local_dval;
- }
-#if WITH_BCMATH
- if (length>16) {
- register char *ptr=str, *end=str+length;
-
- while(ptr<end) {
- switch(*ptr++) {
- case 'e':
- case 'E':
- /* scientific notation, not handled by the BC library */
- return IS_DOUBLE;
- break;
- default:
- break;
- }
- }
- return FLAG_IS_BC;
- } else {
- return IS_DOUBLE;
- }
-#else
- return IS_DOUBLE;
-#endif
- }
-
- return 0;
-}
-
-#else
+#if 0
static inline int is_numeric_string(char *str, int length, long *lval, double *dval)
{
View
63 Zend/zend_operators.h
@@ -21,6 +21,8 @@
#ifndef _OPERATORS_H
#define _OPERATORS_H
+#include <errno.h>
+
#define MAX_LENGTH_OF_LONG 18
#define MAX_LENGTH_OF_DOUBLE 32
@@ -47,7 +49,66 @@ ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2);
-ZEND_API inline int is_numeric_string(char *str, int length, long *lval, double *dval);
+ZEND_API inline int is_numeric_string(char *str, int length, long *lval, double *dval)
+#if defined(C0X_INLINE_SEMANTICS)
+{
+ long local_lval;
+ double local_dval;
+ char *end_ptr;
+
+ if (!length) {
+ return 0;
+ }
+
+ errno=0;
+ local_lval = strtol(str, &end_ptr, 10);
+ if (errno!=ERANGE && end_ptr == str+length) { /* integer string */
+ if (lval) {
+ *lval = local_lval;
+ }
+ return IS_LONG;
+ }
+
+ errno=0;
+ local_dval = strtod(str, &end_ptr);
+ if (errno!=ERANGE && end_ptr == str+length) { /* floating point string */
+ if (! finite(local_dval)) {
+ /* "inf","nan" and maybe other weird ones */
+ return 0;
+ }
+
+ if (dval) {
+ *dval = local_dval;
+ }
+#if WITH_BCMATH
+ if (length>16) {
+ register char *ptr=str, *end=str+length;
+
+ while(ptr<end) {
+ switch(*ptr++) {
+ case 'e':
+ case 'E':
+ /* scientific notation, not handled by the BC library */
+ return IS_DOUBLE;
+ break;
+ default:
+ break;
+ }
+ }
+ return FLAG_IS_BC;
+ } else {
+ return IS_DOUBLE;
+ }
+#else
+ return IS_DOUBLE;
+#endif
+ }
+
+ return 0;
+}
+#else
+;
+#endif
ZEND_API int increment_function(zval *op1);
ZEND_API int decrement_function(zval *op2);
Please sign in to comment.
Something went wrong with that request. Please try again.