summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorAndi Gutmans <andi@php.net>2002-03-02 20:38:52 +0000
committerAndi Gutmans <andi@php.net>2002-03-02 20:38:52 +0000
commitb90d80b58806083ded586da0745f02b38d301819 (patch)
tree052b205bd3fb76749def1abdfd3094fd022279aa /Zend
parentbc7e0b55121755e35e1a659e1d82822e3b7fcde8 (diff)
downloadphp-git-b90d80b58806083ded586da0745f02b38d301819.tar.gz
- Initial patch to support importing from class scopes (for Stig).
- It isn't complete yet but I want to work on it from another machine. It - shouldn't break anything else so just don't try and use it. - The following is a teaser of something that already works: <?php class MyClass { function hello() { print "Hello, World\n"; } class MyClass2 { function hello() { print "Hello, World in MyClass2\n"; } } } import function hello, class MyClass2 from MyClass; MyClass2::hello(); hello(); ?>
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_compile.c54
-rw-r--r--Zend/zend_compile.h22
-rw-r--r--Zend/zend_execute.c61
-rw-r--r--Zend/zend_globals.h2
-rw-r--r--Zend/zend_language_parser.y30
-rw-r--r--Zend/zend_language_scanner.l8
6 files changed, 166 insertions, 11 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 33216efa87..997848d350 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -552,6 +552,60 @@ zend_bool zend_is_function_or_method_call(znode *variable)
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)
{
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index aa2043a938..4b00f5727b 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -366,6 +366,10 @@ void zend_do_extended_fcall_end(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
@@ -540,16 +544,20 @@ int zendlex(znode *zendlval TSRMLS_DC);
#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 */
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index a45781a2ba..b9d91e06c3 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1402,6 +1402,67 @@ binary_assign_op_addr: {
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) {
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 2139e54fcf..7b029b0e31 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -119,6 +119,8 @@ struct _zend_compiler_globals {
int interactive;
zend_bool increment_lineno;
+
+ zend_llist import_commands;
};
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index accea627e6..0e36bc02a5 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -135,6 +135,7 @@
%token T_DOLLAR_OPEN_CURLY_BRACES
%token T_CURLY_OPEN
%token T_PAAMAYIM_NEKUDOTAYIM
+%token T_IMPORT T_FROM
%% /* Rules */
@@ -206,10 +207,31 @@ unticked_statement:
| 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:
@@ -218,8 +240,8 @@ 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); }
;
@@ -542,7 +564,7 @@ parse_class_name_entry:
| 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); }
;
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index 16ad7d8c82..d3b2f03c4e 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -669,6 +669,14 @@ NEWLINE ("\r"|"\n"|"\r\n")
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;
}