Skip to content

Instantly share code, notes, and snippets.

@bwoebi
Last active December 24, 2015 00:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bwoebi/6720403 to your computer and use it in GitHub Desktop.
Save bwoebi/6720403 to your computer and use it in GitHub Desktop.
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index d789f3c..8fca9ae 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2226,33 +2226,28 @@ void zend_resolve_class_name(znode *class_name TSRMLS_DC) /* {{{ */
/* }}} */
void zend_do_create_anon_class(znode *result TSRMLS_DC) { /* {{{ */
- char *class_name = NULL;
- int class_name_len = 0;
-
- CG(anon_class_id)++;
-
- result->op_type = IS_CONST;
-
- Z_TYPE(result->u.constant) = IS_STRING;
- class_name_len = snprintf(
- NULL, 0, "Class$$%lu", CG(anon_class_id));
- class_name = (char*) emalloc(class_name_len+1);
- snprintf(
- class_name, class_name_len+1,
- "Class$$%lu", CG(anon_class_id)
- );
- class_name[class_name_len] = '\0';
-
- Z_STRLEN(result->u.constant) = class_name_len;
- Z_STRVAL(result->u.constant) = (char*) zend_new_interned_string(
- class_name, class_name_len+1, 1 TSRMLS_CC);
+ char *class_name = NULL;
+ int class_name_len = 0;
+
+ CG(anon_class_id)++;
+
+ result->op_type = IS_CONST;
+
+ Z_TYPE(result->u.constant) = IS_STRING;
+ class_name_len = snprintf(NULL, 0, "Class$$%lu", CG(anon_class_id));
+ class_name = (char*) emalloc(class_name_len+1);
+ snprintf(class_name, class_name_len+1, "Class$$%lu", CG(anon_class_id));
+ class_name[class_name_len] = '\0';
+
+ Z_STRLEN(result->u.constant) = class_name_len;
+ Z_STRVAL(result->u.constant) = class_name;
} /* }}} */
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
{
long fetch_class_op_number;
zend_op *opline;
-
+
fetch_class_op_number = get_next_op_number(CG(active_op_array));
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 3bc5ffc..71360c0 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -150,9 +150,11 @@ struct _zend_compiler_globals {
zend_bool multibyte;
zend_bool detect_unicode;
zend_bool encoding_declared;
-
+
/* anonymous classes */
- zend_ulong anon_class_id;
+ zend_ulong anon_class_id;
+ znode anon_class_name;
+ int anon_class_opline_num;
#ifdef ZTS
zval ***static_members_table;
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 5a7dc08..c673d8b 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -731,42 +731,77 @@ instance_call:
chaining_instance_call { zend_do_pop_object(&$$ TSRMLS_CC); zend_do_end_variable_parse(&$2, BP_VAR_R, 0 TSRMLS_CC); }
;
-new_object:
- T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
-;
-
-anon_class_type:
- T_CLASS {
- $$.u.op.opline_num = CG(zend_lineno);
- $$.EA = ZEND_ACC_ANON_CLASS;
- }
-;
-
-anon_class_decl:
- anon_class_type {
- zend_do_create_anon_class(&$$ TSRMLS_CC);
- } extends_from {
- zend_do_begin_class_declaration(&$1, &$2, &$3 TSRMLS_CC);
- } implements_list
- '{' class_statement_list '}' {
- zend_do_end_class_declaration(&$1, &$3 TSRMLS_CC);
- zend_do_fetch_class(&$$, &$2 TSRMLS_CC);
- }
+anon_implements_list:
+ /* empty */ { $$.EA = 0; }
+ | T_IMPLEMENTS {
+ $1.u.op.opline_num = CG(zend_lineno);
+ $1.EA = ZEND_ACC_ANON_CLASS;
+ zend_do_fetch_class(&CG(anon_class_name), &CG(anon_class_name) TSRMLS_CC);
+ znode parent = CG(anon_class_name);
+ zend_do_create_anon_class(&$$ TSRMLS_CC);
+ CG(anon_class_name) = $$;
+ zval_copy_ctor(&CG(anon_class_name).u.constant);
+ zend_do_begin_class_declaration(&$1, &$$, &parent TSRMLS_CC);
+ $1.EA = CG(active_op_array)->last;
+ CG(active_op_array)->last = CG(anon_class_opline_num);
+ } interface_list {
+ CG(anon_class_opline_num) = CG(active_op_array)->last;
+ CG(active_op_array)->last = $1.EA;
+ $$ = $1;
+ }
;
-new_anon_object:
- T_NEW anon_class_decl {
- zend_do_extended_fcall_begin(TSRMLS_C);
- zend_do_begin_new_object(&$1, &$2 TSRMLS_CC);
- } ctor_arguments {
- zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC);
- zend_do_extended_fcall_end(TSRMLS_C);
- }
+optional_anon_class:
+ /* empty */ { $$.EA = 0; }
+ | anon_implements_list {
+ zend_bool interfaces = $1.EA;
+ $1.u.op.opline_num = CG(zend_lineno);
+ $1.EA = ZEND_ACC_ANON_CLASS;
+ if (!interfaces) {
+ zend_do_fetch_class(&CG(anon_class_name), &CG(anon_class_name) TSRMLS_CC);
+ znode parent = CG(anon_class_name);
+ zend_do_create_anon_class(&$$ TSRMLS_CC);
+ CG(anon_class_name) = $$;
+ zval_copy_ctor(&CG(anon_class_name).u.constant);
+ zend_do_begin_class_declaration(&$1, &$$, &parent TSRMLS_CC);
+ } else {
+ $$ = CG(anon_class_name);
+ }
+ } '{' class_statement_list '}' {
+ zend_do_fetch_class(&$$, &CG(anon_class_name) TSRMLS_CC);
+ zend_do_end_class_declaration(&$1, &$2 TSRMLS_CC);
+ $$.EA = 1;
+ }
;
new_expr:
- new_object
- | new_anon_object
+ T_NEW class_name {
+ zend_uchar i = 0;
+ while (i++ < 4) {
+ get_next_op(CG(active_op_array) TSRMLS_CC)->opcode = ZEND_NOP;
+ }
+ zend_do_extended_fcall_begin(TSRMLS_C);
+ zend_do_begin_new_object(&$1, &$2 TSRMLS_CC);
+ } ctor_arguments {
+ CG(anon_class_opline_num) = CG(active_op_array)->last;
+ CG(active_op_array)->last = $1.u.op.opline_num - ((CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)?6:5);
+ CG(anon_class_name) = $2;
+ } optional_anon_class {
+ CG(active_op_array)->last = CG(anon_class_opline_num);
+ if ($6.EA) {
+ CG(active_op_array)->opcodes[$1.u.op.opline_num].op1_type = IS_VAR;
+ CG(active_op_array)->opcodes[$1.u.op.opline_num].op1.var = $6.u.op.var;
+ }
+ zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC);
+ zend_do_extended_fcall_end(TSRMLS_C);
+ }
+ | T_NEW dynamic_class_name_reference {
+ zend_do_extended_fcall_begin(TSRMLS_C);
+ zend_do_begin_new_object(&$1, &$2 TSRMLS_CC);
+ } ctor_arguments {
+ zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC);
+ zend_do_extended_fcall_end(TSRMLS_C);
+ }
;
expr_without_variable:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment