Permalink
Browse files

This patch is a go. Not fully optimized yet, but working properly.

Prepatch tagged as BEFORE_STACK_PATCH.
  • Loading branch information...
1 parent b06c573 commit 39a7f4c306675d3a03ff56f0a8c7f5e2183ab09a @zsuraski zsuraski committed Apr 12, 1999
Showing with 151 additions and 88 deletions.
  1. +15 −15 Zend/zend-parser.y
  2. +1 −1 Zend/zend.h
  3. +39 −27 Zend/zend_API.c
  4. +4 −4 Zend/zend_API.h
  5. +7 −7 Zend/zend_compile.c
  6. +3 −2 Zend/zend_compile.h
  7. +37 −30 Zend/zend_execute.c
  8. +4 −0 Zend/zend_execute.h
  9. +37 −2 Zend/zend_execute_API.c
  10. +2 −0 Zend/zend_globals.h
  11. +2 −0 Zend/zend_ptr_stack.c
View
@@ -253,10 +253,10 @@ parameter_list:
non_empty_parameter_list:
- VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=0; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
- | '&' VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=0; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
- | ZEND_CONST VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=0; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
- | VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=0; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$3, BYREF_NONE CLS_CC); }
+ VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
+ | '&' VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
+ | ZEND_CONST VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
+ | VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$3, BYREF_NONE CLS_CC); }
| non_empty_parameter_list ',' VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$3, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
| non_empty_parameter_list ',' '&' VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$4, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
| non_empty_parameter_list ',' ZEND_CONST VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$4, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
@@ -265,15 +265,15 @@ non_empty_parameter_list:
function_call_parameter_list:
- non_empty_function_call_parameter_list
- | /* empty */
+ non_empty_function_call_parameter_list { $$ = $1; }
+ | /* empty */ { $$.u.constant.value.lval = 0; }
;
non_empty_function_call_parameter_list:
- expr_without_variable { $$.u.constant.value.lval = 0; do_pass_param(&$1, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
- | cvar { $$.u.constant.value.lval = 0; do_pass_param(&$1, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
- | '&' w_cvar { $$.u.constant.value.lval = 0; do_pass_param(&$2, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
+ expr_without_variable { $$.u.constant.value.lval = 1; do_pass_param(&$1, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
+ | cvar { $$.u.constant.value.lval = 1; do_pass_param(&$1, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
+ | '&' w_cvar { $$.u.constant.value.lval = 1; do_pass_param(&$2, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
| non_empty_function_call_parameter_list ',' expr_without_variable { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$3, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
| non_empty_function_call_parameter_list ',' cvar { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$3, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
| non_empty_function_call_parameter_list ',' '&' w_cvar { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$4, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
@@ -343,7 +343,7 @@ expr_without_variable:
ZEND_LIST '(' { do_list_init(); } assignment_list ')' '=' expr { do_list_end(&$$, &$7 CLS_CC); }
| w_cvar '=' expr { do_assign(&$$, &$1, &$3 CLS_CC); }
| w_cvar '=' '&' w_cvar { do_assign_ref(&$$, &$1, &$4 CLS_CC); }
- | w_cvar '=' NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$2, &$1, &$3, &$4 CLS_CC); } ctor_arguments { do_end_new_object(&$4, &$3 CLS_CC); do_extended_fcall_end(CLS_C); $$ = $2;}
+ | w_cvar '=' NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$2, &$1, &$3, &$4 CLS_CC); } ctor_arguments { do_end_new_object(&$4, &$3, &$6 CLS_CC); do_extended_fcall_end(CLS_C); $$ = $2;}
| rw_cvar PLUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 CLS_CC); }
| rw_cvar MINUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 CLS_CC); }
| rw_cvar MUL_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 CLS_CC); }
@@ -391,13 +391,13 @@ expr_without_variable:
expr { do_qm_false(&$$, &$7, &$2, &$5 CLS_CC); }
| STRING '(' { do_extended_fcall_begin(CLS_C); do_begin_function_call(&$1 CLS_CC); }
function_call_parameter_list
- ')' { do_end_function_call(&$1, &$$, 0 CLS_CC); do_extended_fcall_end(CLS_C); }
+ ')' { do_end_function_call(&$1, &$$, &$4, 0 CLS_CC); do_extended_fcall_end(CLS_C); }
| r_cvar '(' { do_extended_fcall_begin(CLS_C); do_begin_dynamic_function_call(&$1 CLS_CC); }
function_call_parameter_list
- ')' { do_end_function_call(&$1, &$$, 0 CLS_CC); do_extended_fcall_end(CLS_C);}
+ ')' { do_end_function_call(&$1, &$$, &$4, 0 CLS_CC); do_extended_fcall_end(CLS_C);}
| STRING T_PAAMAYIM_NEKUDOTAYIM STRING '(' { do_extended_fcall_begin(CLS_C); do_begin_class_member_function_call(&$1, &$3 CLS_CC); }
function_call_parameter_list
- ')' { do_end_function_call(&$3, &$$, 1 CLS_CC); do_extended_fcall_end(CLS_C);}
+ ')' { do_end_function_call(&$3, &$$, &$6, 1 CLS_CC); do_extended_fcall_end(CLS_C);}
| internal_functions_in_yacc { $$ = $1; }
| INT_CAST expr { do_cast(&$$, &$2, IS_LONG CLS_CC); }
| DOUBLE_CAST expr { do_cast(&$$, &$2, IS_DOUBLE CLS_CC); }
@@ -421,8 +421,8 @@ exit_expr:
ctor_arguments:
- /* empty */
- | '(' function_call_parameter_list ')'
+ /* empty */ { $$.u.constant.value.lval=0; }
+ | '(' function_call_parameter_list ')' { $$ = $2; }
;
View
@@ -46,7 +46,7 @@
#include "zend_llist.h"
-#define INTERNAL_FUNCTION_PARAMETERS HashTable *ht, zval *return_value, HashTable *list, HashTable *plist
+#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, HashTable *list, HashTable *plist
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, list, plist
/*
View
@@ -31,21 +31,23 @@ static int module_count=0;
HashTable list_destructors, module_registry;
/* this function doesn't check for too many parameters */
-int getParameters(HashTable *ht, int param_count,...)
+int getParameters(int ht, int param_count,...)
{
+ void **p = EG(argument_stack).elements+EG(argument_stack).top-1;
+ int arg_count = (ulong) *p;
va_list ptr;
- zval **param, **tmp = NULL, *param_ptr;
- int i;
+ zval **param, *param_ptr;
+ ELS_FETCH();
+
+ if (param_count>arg_count) {
+ return FAILURE;
+ }
va_start(ptr, param_count);
- for (i = 0; i < param_count; i++) {
+ do {
param = va_arg(ptr, zval **);
- if (zend_hash_index_find(ht, i, (void **) &tmp) == FAILURE) {
- va_end(ptr);
- return FAILURE;
- }
- param_ptr = *tmp;
+ param_ptr = *(p-param_count);
if (!param_ptr->is_ref && param_ptr->refcount>1) {
zval *new_tmp;
@@ -55,25 +57,30 @@ int getParameters(HashTable *ht, int param_count,...)
new_tmp->refcount = 1;
new_tmp->is_ref = 0;
param_ptr = new_tmp;
- zend_hash_index_update(ht, i, &param_ptr, sizeof(zval *), NULL);
+ *(p-param_count) = param_ptr;
}
*param = param_ptr;
- }
+ } while (--param_count);
va_end(ptr);
+
return SUCCESS;
}
-int getParametersArray(HashTable *ht, int param_count, zval **argument_array)
+int getParametersArray(int ht, int param_count, zval **argument_array)
{
- int i;
- zval **tmp = NULL, *param_ptr;
+ void **p = EG(argument_stack).elements+EG(argument_stack).top-1;
+ int arg_count = (ulong) *p;
+ zval *param_ptr;
+ ELS_FETCH();
- for (i = 0; i < param_count; i++) {
- if (zend_hash_index_find(ht, i, (void **) &tmp) == FAILURE) {
- return FAILURE;
- }
- param_ptr = *tmp;
+ if (param_count>arg_count) {
+ return FAILURE;
+ }
+
+
+ do {
+ param_ptr = *(p-param_count);
if (!param_ptr->is_ref && param_ptr->refcount>1) {
zval *new_tmp;
@@ -83,10 +90,11 @@ int getParametersArray(HashTable *ht, int param_count, zval **argument_array)
new_tmp->refcount = 1;
new_tmp->is_ref = 0;
param_ptr = new_tmp;
- zend_hash_index_update(ht, i, &param_ptr, sizeof(zval *), NULL);
+ *(p-param_count) = param_ptr;
}
- argument_array[i] = param_ptr;
- }
+ *(argument_array++) = param_ptr;
+ } while (--param_count);
+
return SUCCESS;
}
@@ -106,14 +114,18 @@ int getThis(zval **this)
return SUCCESS;
}
-int ParameterPassedByReference(HashTable *ht, uint n)
+int ParameterPassedByReference(int ht, uint n)
{
- zval **tmp;
+ void **p = EG(argument_stack).elements+EG(argument_stack).top-1;
+ ulong arg_count = (ulong) *p;
+ zval *arg;
+ ELS_FETCH();
- if (zend_hash_index_find(ht, n-1, (void **) &tmp) == FAILURE) {
- return 0;
+ if (n>arg_count) {
+ return FAILURE;
}
- return (*tmp)->is_ref;
+ arg = (zval *) *(p-arg_count+n);
+ return arg->is_ref;
}
View
@@ -23,10 +23,10 @@
int zend_next_free_module(void);
-int getParameters(HashTable *ht, int param_count,...);
-int getParametersArray(HashTable *ht, int param_count, zval **argument_array);
+int getParameters(int ht, int param_count,...);
+int getParametersArray(int ht, int param_count, zval **argument_array);
int getThis(zval **this);
-int ParameterPassedByReference(HashTable *ht, uint n);
+int ParameterPassedByReference(int ht, uint n);
int register_functions(function_entry *functions);
void unregister_functions(function_entry *functions, int count);
int register_module(zend_module_entry *module_entry);
@@ -36,7 +36,7 @@ ZEND_API void wrong_param_count(void);
#define WRONG_PARAM_COUNT { wrong_param_count(); return; }
#define WRONG_PARAM_COUNT_WITH_RETVAL(ret) { wrong_param_count(); return ret; }
-#define ARG_COUNT(ht) (ht->nNextFreeElement)
+#define ARG_COUNT(ht) (ht)
#define BYREF_NONE 0
#define BYREF_FORCE 1
View
@@ -702,7 +702,6 @@ void do_begin_function_call(znode *function_name CLS_DC)
}
break;
}
-
opline->opcode = ZEND_INIT_FCALL;
SET_UNUSED(opline->op1);
SET_UNUSED(opline->op2);
@@ -741,7 +740,7 @@ void do_begin_class_member_function_call(znode *class_name, znode *function_name
}
-void do_end_function_call(znode *function_name, znode *result, int is_method CLS_DC)
+void do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method CLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
ELS_FETCH();
@@ -754,6 +753,7 @@ void do_end_function_call(znode *function_name, znode *result, int is_method CLS
SET_UNUSED(opline->op2);
opline->op2.u.constant.value.lval = is_method;
zend_stack_del_top(&CG(function_call_stack));
+ opline->extended_value = argument_list->u.constant.value.lval;
}
@@ -777,8 +777,8 @@ void do_pass_param(znode *param, int op, int offset CLS_DC)
break;
}
}
- if (arg_types && offset<arg_types[0]
- && arg_types[1+offset]==BYREF_FORCE) {
+ if (arg_types && offset<=arg_types[0]
+ && arg_types[offset]==BYREF_FORCE) {
/* change to passing by reference */
switch (param->op_type) {
case IS_VAR:
@@ -1223,14 +1223,14 @@ void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode
}
-void do_end_new_object(znode *class_name, znode *new_token CLS_DC)
+void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list CLS_DC)
{
znode ctor_result;
if (class_name->op_type == IS_CONST) {
zval_copy_ctor(&class_name->u.constant);
}
- do_end_function_call(class_name, &ctor_result, 1 CLS_CC);
+ do_end_function_call(class_name, &ctor_result, argument_list, 1 CLS_CC);
do_free(&ctor_result CLS_CC);
CG(active_op_array)->opcodes[new_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
@@ -1438,7 +1438,7 @@ void do_list_end(znode *result, znode *expr CLS_DC)
le = CG(list_llist).head;
while (le) {
do_assign(result, &((list_llist_element *) le->data)->var, &((list_llist_element *) le->data)->value CLS_CC);
- EG(active_op_array)->opcodes[EG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
+ CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
le = le->next;
}
zend_llist_destroy(&CG(dimension_llist));
View
@@ -62,6 +62,7 @@ typedef struct _zend_op {
znode result;
znode op1;
znode op2;
+ ulong extended_value;
char *filename;
uint lineno;
} zend_op;
@@ -238,7 +239,7 @@ void do_receive_arg(int op, znode *var, znode *offset, znode *initialization, un
void do_begin_function_call(znode *function_name CLS_DC);
void do_begin_dynamic_function_call(znode *function_name CLS_DC);
void do_begin_class_member_function_call(znode *class_name, znode *function_name CLS_DC);
-void do_end_function_call(znode *function_name, znode *result, int is_method CLS_DC);
+void do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method CLS_DC);
void do_return(znode *expr CLS_DC);
void do_pass_param(znode *param, int op, int offset CLS_DC);
@@ -269,7 +270,7 @@ void do_pop_object(znode *object CLS_DC);
void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode *class_name CLS_DC);
-void do_end_new_object(znode *class_name, znode *new_token CLS_DC);
+void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list CLS_DC);
void do_fetch_constant(znode *result, znode *constant_name, int mode CLS_DC);
Oops, something went wrong.

0 comments on commit 39a7f4c

Please sign in to comment.