return ((type & ZEND_PARSED_METHOD_CALL) || (type == ZEND_PARSED_FUNCTION_CALL));
}
+void zend_do_begin_import(TSRMLS_D)
+{
+ zend_llist_init(&CG(import_commands), sizeof(zend_op), NULL, 0);
+}
+
+void zend_do_import(int type, znode *what TSRMLS_DC)
+{
+ zend_op opline;
+
+ init_op(&opline TSRMLS_CC);
+
+ switch (type) {
+ case T_FUNCTION:
+ opline.opcode = ZEND_IMPORT_FUNCTION;
+ break;
+ case T_CLASS:
+ opline.opcode = ZEND_IMPORT_CLASS;
+ break;
+ case T_CONST:
+ opline.opcode = ZEND_IMPORT_CONST;
+ break;
+ }
+
+ if (what) {
+ if (type == T_FUNCTION || type == T_CLASS) {
+ zend_str_tolower(what->u.constant.value.str.val, what->u.constant.value.str.len);
+ }
+ opline.op2 = *what;
+ } else {
+ SET_UNUSED(opline.op2);
+ }
+
+ zend_llist_add_element(&CG(import_commands), &opline);
+}
+
+void zend_do_end_import(znode *import_from TSRMLS_DC)
+{
+ zend_llist_element *le;
+ zend_op *opline, *opline_ptr;
+
+
+ le = CG(import_commands).head;
+
+ while (le) {
+ opline_ptr = (zend_op *)le->data;
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ memcpy(opline, opline_ptr, sizeof(zend_op));
+ opline->op1 = *import_from;
+ le = le->next;
+ }
+ zend_llist_destroy(&CG(import_commands));
+}
+
+
void zend_do_begin_variable_parse(TSRMLS_D)
{
void zend_do_ticks(TSRMLS_D);
+void zend_do_begin_import(TSRMLS_D);
+void zend_do_import(int type, znode *what TSRMLS_DC);
+void zend_do_end_import(znode *import_from TSRMLS_DC);
+
ZEND_API void function_add_ref(zend_function *function);
#define INITIAL_OP_ARRAY_SIZE 64
#define ZEND_CATCH 107
#define ZEND_THROW 108
-#define ZEND_FETCH_CLASS 110
+#define ZEND_FETCH_CLASS 109
+
+#define ZEND_CLONE 110
-#define ZEND_CLONE 111
+#define ZEND_INIT_CTOR_CALL 111
+#define ZEND_INIT_METHOD_CALL 112
+#define ZEND_INIT_STATIC_METHOD_CALL 113
-#define ZEND_INIT_CTOR_CALL 112
-#define ZEND_INIT_METHOD_CALL 113
-#define ZEND_INIT_STATIC_METHOD_CALL 114
+#define ZEND_ISSET_ISEMPTY_VAR 114
+#define ZEND_ISSET_ISEMPTY_DIM_OBJ 115
-#define ZEND_ISSET_ISEMPTY_VAR 115
-#define ZEND_ISSET_ISEMPTY_DIM_OBJ 116
+#define ZEND_IMPORT_FUNCTION 116
+#define ZEND_IMPORT_CLASS 117
+#define ZEND_IMPORT_CONST 118
/* end of block */
FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
}
NEXT_OPCODE();
+ case ZEND_IMPORT_FUNCTION:
+ {
+ zend_class_entry *ce;
+ zend_function *function;
+
+ ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
+
+ if (EX(opline)->op2.op_type != IS_UNUSED) {
+ char *function_name_strval;
+ int function_name_strlen;
+
+ function_name_strval = EX(opline)->op2.u.constant.value.str.val;
+ function_name_strlen = EX(opline)->op2.u.constant.value.str.len;
+
+ if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen + 1, (void **) &function)==FAILURE) {
+ zend_error(E_ERROR, "Import: function %s() not found", function_name_strval);
+ }
+ if (zend_hash_add(EG(function_table), function_name_strval, function_name_strlen + 1, function, sizeof(zend_function), NULL) == FAILURE) {
+ zend_error(E_ERROR, "Import: function %s() already exists in current scope", function_name_strval);
+ }
+ function_add_ref(function);
+ } else {
+ //zend_hash_apply(&ce->function_table, (apply_func_t) zend_import_function, (void *) 1 TSRMLS_CC);
+ }
+ NEXT_OPCODE();
+ }
+ case ZEND_IMPORT_CLASS:
+ {
+ zend_class_entry *ce;
+ zend_class_entry *import_ce;
+
+ ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
+
+ if (EX(opline)->op2.op_type != IS_UNUSED) {
+ char *class_name_strval;
+ int class_name_strlen;
+
+ class_name_strval = EX(opline)->op2.u.constant.value.str.val;
+ class_name_strlen = EX(opline)->op2.u.constant.value.str.len;
+
+ if (zend_hash_find(&ce->class_table, class_name_strval, class_name_strlen + 1, (void **) &import_ce)==FAILURE) {
+ zend_error(E_ERROR, "Import: class %s not found", class_name_strval);
+ }
+ if (zend_hash_add(EG(class_table), class_name_strval, class_name_strlen + 1, import_ce, sizeof(zend_class_entry), NULL) == FAILURE) {
+ zend_error(E_ERROR, "Import: class %s already exists in current scope", class_name_strval);
+ }
+ zend_class_add_ref(import_ce);
+ } else {
+ //zend_hash_apply(&ce->function_table, (apply_func_t) zend_import_function, (void *) 1 TSRMLS_CC);
+ }
+
+ NEXT_OPCODE();
+ }
+ case ZEND_IMPORT_CONST:
+ {
+ zend_class_entry *ce;
+
+ ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
+
+ NEXT_OPCODE();
+ }
case ZEND_FETCH_CLASS:
{
if (EX(opline)->op1.op_type == IS_UNUSED) {
int interactive;
zend_bool increment_lineno;
+
+ zend_llist import_commands;
};
%token T_DOLLAR_OPEN_CURLY_BRACES
%token T_CURLY_OPEN
%token T_PAAMAYIM_NEKUDOTAYIM
+%token T_IMPORT T_FROM
%% /* Rules */
| T_DECLARE { zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(TSRMLS_C); }
| ';' /* empty statement */
| T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}'
- T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$8, &$9, 1 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+ T_CATCH '(' catch_or_import_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$8, &$9, 1 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
additional_catches
| T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
| T_DELETE cvar ';' { zend_do_end_variable_parse(BP_VAR_UNSET, 0 TSRMLS_CC); zend_do_unset(&$1, ZEND_UNSET_OBJ TSRMLS_CC); }
+ | T_IMPORT { zend_do_begin_import(TSRMLS_C); } import_rule T_FROM catch_or_import_class_entry { zend_do_end_import(&$5 TSRMLS_CC); } ';'
+;
+
+
+import_rule:
+ '*' { zend_do_import(T_FUNCTION, NULL TSRMLS_CC); zend_do_import(T_CLASS, NULL TSRMLS_CC); zend_do_import(T_CONST, NULL TSRMLS_CC); }
+ | import_commands
+;
+
+import_commands:
+ import_commands ',' import_command
+ | import_command
+;
+
+import_command:
+ T_FUNCTION T_STRING { zend_do_import(T_FUNCTION, &$2 TSRMLS_CC); }
+ | T_CLASS T_STRING { zend_do_import(T_CLASS, &$2 TSRMLS_CC); }
+ | T_CONST T_STRING { zend_do_import(T_CONST, &$2 TSRMLS_CC); }
+ | T_FUNCTION '*' { zend_do_import(T_FUNCTION, NULL TSRMLS_CC); }
+ | T_CLASS '*' { zend_do_import(T_CLASS, NULL TSRMLS_CC); }
+ | T_CONST '*' { zend_do_import(T_CONST, NULL TSRMLS_CC); }
;
additional_catches:
;
non_empty_additional_catches:
- non_empty_additional_catches T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$2, &$4, &$5, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$2 TSRMLS_CC); }
- | T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$4, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+ non_empty_additional_catches T_CATCH '(' catch_or_import_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$2, &$4, &$5, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$2 TSRMLS_CC); }
+ | T_CATCH '(' catch_or_import_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$4, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
;
| T_STRING T_PAAMAYIM_NEKUDOTAYIM { $$ = $1; zend_str_tolower($$.u.constant.value.str.val, $$.u.constant.value.str.len); }
;
-catch_class_entry:
+catch_or_import_class_entry:
parse_class_entry T_STRING { do_fetch_class(&$$, &$1, &$2 TSRMLS_CC); }
| T_STRING { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); }
;
return T_INCLUDE;
}
+<ST_IN_SCRIPTING>"import" {
+ return T_IMPORT;
+}
+
+<ST_IN_SCRIPTING>"from" {
+ return T_FROM;
+}
+
<ST_IN_SCRIPTING>"include_once" {
return T_INCLUDE_ONCE;
}