Skip to content

Commit 39a7f4c

Browse files
committed
This patch is a go. Not fully optimized yet, but working properly.
Prepatch tagged as BEFORE_STACK_PATCH.
1 parent b06c573 commit 39a7f4c

File tree

11 files changed

+151
-88
lines changed

11 files changed

+151
-88
lines changed

Zend/zend-parser.y

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,10 @@ parameter_list:
253253

254254

255255
non_empty_parameter_list:
256-
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); }
257-
| '&' 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); }
258-
| 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); }
259-
| 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); }
256+
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); }
257+
| '&' 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); }
258+
| 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); }
259+
| 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); }
260260
| 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); }
261261
| 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); }
262262
| 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:
265265

266266

267267
function_call_parameter_list:
268-
non_empty_function_call_parameter_list
269-
| /* empty */
268+
non_empty_function_call_parameter_list { $$ = $1; }
269+
| /* empty */ { $$.u.constant.value.lval = 0; }
270270
;
271271

272272

273273
non_empty_function_call_parameter_list:
274-
expr_without_variable { $$.u.constant.value.lval = 0; do_pass_param(&$1, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
275-
| cvar { $$.u.constant.value.lval = 0; do_pass_param(&$1, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
276-
| '&' w_cvar { $$.u.constant.value.lval = 0; do_pass_param(&$2, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
274+
expr_without_variable { $$.u.constant.value.lval = 1; do_pass_param(&$1, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
275+
| cvar { $$.u.constant.value.lval = 1; do_pass_param(&$1, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
276+
| '&' w_cvar { $$.u.constant.value.lval = 1; do_pass_param(&$2, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
277277
| 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); }
278278
| 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); }
279279
| 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:
343343
ZEND_LIST '(' { do_list_init(); } assignment_list ')' '=' expr { do_list_end(&$$, &$7 CLS_CC); }
344344
| w_cvar '=' expr { do_assign(&$$, &$1, &$3 CLS_CC); }
345345
| w_cvar '=' '&' w_cvar { do_assign_ref(&$$, &$1, &$4 CLS_CC); }
346-
| 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;}
346+
| 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;}
347347
| rw_cvar PLUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 CLS_CC); }
348348
| rw_cvar MINUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 CLS_CC); }
349349
| rw_cvar MUL_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 CLS_CC); }
@@ -391,13 +391,13 @@ expr_without_variable:
391391
expr { do_qm_false(&$$, &$7, &$2, &$5 CLS_CC); }
392392
| STRING '(' { do_extended_fcall_begin(CLS_C); do_begin_function_call(&$1 CLS_CC); }
393393
function_call_parameter_list
394-
')' { do_end_function_call(&$1, &$$, 0 CLS_CC); do_extended_fcall_end(CLS_C); }
394+
')' { do_end_function_call(&$1, &$$, &$4, 0 CLS_CC); do_extended_fcall_end(CLS_C); }
395395
| r_cvar '(' { do_extended_fcall_begin(CLS_C); do_begin_dynamic_function_call(&$1 CLS_CC); }
396396
function_call_parameter_list
397-
')' { do_end_function_call(&$1, &$$, 0 CLS_CC); do_extended_fcall_end(CLS_C);}
397+
')' { do_end_function_call(&$1, &$$, &$4, 0 CLS_CC); do_extended_fcall_end(CLS_C);}
398398
| STRING T_PAAMAYIM_NEKUDOTAYIM STRING '(' { do_extended_fcall_begin(CLS_C); do_begin_class_member_function_call(&$1, &$3 CLS_CC); }
399399
function_call_parameter_list
400-
')' { do_end_function_call(&$3, &$$, 1 CLS_CC); do_extended_fcall_end(CLS_C);}
400+
')' { do_end_function_call(&$3, &$$, &$6, 1 CLS_CC); do_extended_fcall_end(CLS_C);}
401401
| internal_functions_in_yacc { $$ = $1; }
402402
| INT_CAST expr { do_cast(&$$, &$2, IS_LONG CLS_CC); }
403403
| DOUBLE_CAST expr { do_cast(&$$, &$2, IS_DOUBLE CLS_CC); }
@@ -421,8 +421,8 @@ exit_expr:
421421

422422

423423
ctor_arguments:
424-
/* empty */
425-
| '(' function_call_parameter_list ')'
424+
/* empty */ { $$.u.constant.value.lval=0; }
425+
| '(' function_call_parameter_list ')' { $$ = $2; }
426426
;
427427

428428

Zend/zend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
#include "zend_llist.h"
4747

4848

49-
#define INTERNAL_FUNCTION_PARAMETERS HashTable *ht, zval *return_value, HashTable *list, HashTable *plist
49+
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, HashTable *list, HashTable *plist
5050
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, list, plist
5151

5252
/*

Zend/zend_API.c

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,23 @@ static int module_count=0;
3131
HashTable list_destructors, module_registry;
3232

3333
/* this function doesn't check for too many parameters */
34-
int getParameters(HashTable *ht, int param_count,...)
34+
int getParameters(int ht, int param_count,...)
3535
{
36+
void **p = EG(argument_stack).elements+EG(argument_stack).top-1;
37+
int arg_count = (ulong) *p;
3638
va_list ptr;
37-
zval **param, **tmp = NULL, *param_ptr;
38-
int i;
39+
zval **param, *param_ptr;
40+
ELS_FETCH();
41+
42+
if (param_count>arg_count) {
43+
return FAILURE;
44+
}
3945

4046
va_start(ptr, param_count);
4147

42-
for (i = 0; i < param_count; i++) {
48+
do {
4349
param = va_arg(ptr, zval **);
44-
if (zend_hash_index_find(ht, i, (void **) &tmp) == FAILURE) {
45-
va_end(ptr);
46-
return FAILURE;
47-
}
48-
param_ptr = *tmp;
50+
param_ptr = *(p-param_count);
4951
if (!param_ptr->is_ref && param_ptr->refcount>1) {
5052
zval *new_tmp;
5153

@@ -55,25 +57,30 @@ int getParameters(HashTable *ht, int param_count,...)
5557
new_tmp->refcount = 1;
5658
new_tmp->is_ref = 0;
5759
param_ptr = new_tmp;
58-
zend_hash_index_update(ht, i, &param_ptr, sizeof(zval *), NULL);
60+
*(p-param_count) = param_ptr;
5961
}
6062
*param = param_ptr;
61-
}
63+
} while (--param_count);
6264
va_end(ptr);
65+
6366
return SUCCESS;
6467
}
6568

6669

67-
int getParametersArray(HashTable *ht, int param_count, zval **argument_array)
70+
int getParametersArray(int ht, int param_count, zval **argument_array)
6871
{
69-
int i;
70-
zval **tmp = NULL, *param_ptr;
72+
void **p = EG(argument_stack).elements+EG(argument_stack).top-1;
73+
int arg_count = (ulong) *p;
74+
zval *param_ptr;
75+
ELS_FETCH();
7176

72-
for (i = 0; i < param_count; i++) {
73-
if (zend_hash_index_find(ht, i, (void **) &tmp) == FAILURE) {
74-
return FAILURE;
75-
}
76-
param_ptr = *tmp;
77+
if (param_count>arg_count) {
78+
return FAILURE;
79+
}
80+
81+
82+
do {
83+
param_ptr = *(p-param_count);
7784
if (!param_ptr->is_ref && param_ptr->refcount>1) {
7885
zval *new_tmp;
7986

@@ -83,10 +90,11 @@ int getParametersArray(HashTable *ht, int param_count, zval **argument_array)
8390
new_tmp->refcount = 1;
8491
new_tmp->is_ref = 0;
8592
param_ptr = new_tmp;
86-
zend_hash_index_update(ht, i, &param_ptr, sizeof(zval *), NULL);
93+
*(p-param_count) = param_ptr;
8794
}
88-
argument_array[i] = param_ptr;
89-
}
95+
*(argument_array++) = param_ptr;
96+
} while (--param_count);
97+
9098
return SUCCESS;
9199
}
92100

@@ -106,14 +114,18 @@ int getThis(zval **this)
106114
return SUCCESS;
107115
}
108116

109-
int ParameterPassedByReference(HashTable *ht, uint n)
117+
int ParameterPassedByReference(int ht, uint n)
110118
{
111-
zval **tmp;
119+
void **p = EG(argument_stack).elements+EG(argument_stack).top-1;
120+
ulong arg_count = (ulong) *p;
121+
zval *arg;
122+
ELS_FETCH();
112123

113-
if (zend_hash_index_find(ht, n-1, (void **) &tmp) == FAILURE) {
114-
return 0;
124+
if (n>arg_count) {
125+
return FAILURE;
115126
}
116-
return (*tmp)->is_ref;
127+
arg = (zval *) *(p-arg_count+n);
128+
return arg->is_ref;
117129
}
118130

119131

Zend/zend_API.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323

2424
int zend_next_free_module(void);
2525

26-
int getParameters(HashTable *ht, int param_count,...);
27-
int getParametersArray(HashTable *ht, int param_count, zval **argument_array);
26+
int getParameters(int ht, int param_count,...);
27+
int getParametersArray(int ht, int param_count, zval **argument_array);
2828
int getThis(zval **this);
29-
int ParameterPassedByReference(HashTable *ht, uint n);
29+
int ParameterPassedByReference(int ht, uint n);
3030
int register_functions(function_entry *functions);
3131
void unregister_functions(function_entry *functions, int count);
3232
int register_module(zend_module_entry *module_entry);
@@ -36,7 +36,7 @@ ZEND_API void wrong_param_count(void);
3636

3737
#define WRONG_PARAM_COUNT { wrong_param_count(); return; }
3838
#define WRONG_PARAM_COUNT_WITH_RETVAL(ret) { wrong_param_count(); return ret; }
39-
#define ARG_COUNT(ht) (ht->nNextFreeElement)
39+
#define ARG_COUNT(ht) (ht)
4040

4141
#define BYREF_NONE 0
4242
#define BYREF_FORCE 1

Zend/zend_compile.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,6 @@ void do_begin_function_call(znode *function_name CLS_DC)
702702
}
703703
break;
704704
}
705-
706705
opline->opcode = ZEND_INIT_FCALL;
707706
SET_UNUSED(opline->op1);
708707
SET_UNUSED(opline->op2);
@@ -741,7 +740,7 @@ void do_begin_class_member_function_call(znode *class_name, znode *function_name
741740
}
742741

743742

744-
void do_end_function_call(znode *function_name, znode *result, int is_method CLS_DC)
743+
void do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method CLS_DC)
745744
{
746745
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
747746
ELS_FETCH();
@@ -754,6 +753,7 @@ void do_end_function_call(znode *function_name, znode *result, int is_method CLS
754753
SET_UNUSED(opline->op2);
755754
opline->op2.u.constant.value.lval = is_method;
756755
zend_stack_del_top(&CG(function_call_stack));
756+
opline->extended_value = argument_list->u.constant.value.lval;
757757
}
758758

759759

@@ -777,8 +777,8 @@ void do_pass_param(znode *param, int op, int offset CLS_DC)
777777
break;
778778
}
779779
}
780-
if (arg_types && offset<arg_types[0]
781-
&& arg_types[1+offset]==BYREF_FORCE) {
780+
if (arg_types && offset<=arg_types[0]
781+
&& arg_types[offset]==BYREF_FORCE) {
782782
/* change to passing by reference */
783783
switch (param->op_type) {
784784
case IS_VAR:
@@ -1223,14 +1223,14 @@ void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode
12231223
}
12241224

12251225

1226-
void do_end_new_object(znode *class_name, znode *new_token CLS_DC)
1226+
void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list CLS_DC)
12271227
{
12281228
znode ctor_result;
12291229

12301230
if (class_name->op_type == IS_CONST) {
12311231
zval_copy_ctor(&class_name->u.constant);
12321232
}
1233-
do_end_function_call(class_name, &ctor_result, 1 CLS_CC);
1233+
do_end_function_call(class_name, &ctor_result, argument_list, 1 CLS_CC);
12341234
do_free(&ctor_result CLS_CC);
12351235

12361236
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)
14381438
le = CG(list_llist).head;
14391439
while (le) {
14401440
do_assign(result, &((list_llist_element *) le->data)->var, &((list_llist_element *) le->data)->value CLS_CC);
1441-
EG(active_op_array)->opcodes[EG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
1441+
CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
14421442
le = le->next;
14431443
}
14441444
zend_llist_destroy(&CG(dimension_llist));

Zend/zend_compile.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ typedef struct _zend_op {
6262
znode result;
6363
znode op1;
6464
znode op2;
65+
ulong extended_value;
6566
char *filename;
6667
uint lineno;
6768
} zend_op;
@@ -238,7 +239,7 @@ void do_receive_arg(int op, znode *var, znode *offset, znode *initialization, un
238239
void do_begin_function_call(znode *function_name CLS_DC);
239240
void do_begin_dynamic_function_call(znode *function_name CLS_DC);
240241
void do_begin_class_member_function_call(znode *class_name, znode *function_name CLS_DC);
241-
void do_end_function_call(znode *function_name, znode *result, int is_method CLS_DC);
242+
void do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method CLS_DC);
242243
void do_return(znode *expr CLS_DC);
243244

244245
void do_pass_param(znode *param, int op, int offset CLS_DC);
@@ -269,7 +270,7 @@ void do_pop_object(znode *object CLS_DC);
269270

270271

271272
void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode *class_name CLS_DC);
272-
void do_end_new_object(znode *class_name, znode *new_token CLS_DC);
273+
void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list CLS_DC);
273274

274275
void do_fetch_constant(znode *result, znode *constant_name, int mode CLS_DC);
275276

0 commit comments

Comments
 (0)