diff --git a/ext/kernel/memory.c b/ext/kernel/memory.c index 7de519e45b..1cb64ad6ed 100644 --- a/ext/kernel/memory.c +++ b/ext/kernel/memory.c @@ -45,6 +45,16 @@ * Not all methods must grow/restore the zephir_memory_entry. */ +static zend_always_inline zend_execute_data* +find_symbol_table(zend_execute_data* ex) +{ + while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) { + ex = ex->prev_execute_data; + } + + return ex; +} + static zephir_memory_entry* zephir_memory_grow_stack_common(zend_zephir_globals_def *g) { assert(g->start_memory != NULL); @@ -102,8 +112,14 @@ static void zephir_memory_restore_stack_common(zend_zephir_globals_def *g) if (g->active_symbol_table) { active_symbol_table = g->active_symbol_table; while (active_symbol_table && active_symbol_table->scope == active_memory) { - zend_execute_data *ex = EG(current_execute_data); - + zend_execute_data *ex = find_symbol_table(EG(current_execute_data)); +#ifndef ZEPHIR_RELEASE + if (UNEXPECTED(!ex)) { + fprintf(stderr, "ERROR: unable to find a symbol table"); + zephir_print_backtrace(); + return; + } +#endif zend_hash_destroy(ex->symbol_table); efree(ex->symbol_table); ex->symbol_table = active_symbol_table->symbol_table; @@ -387,7 +403,6 @@ void zephir_create_symbol_table() { zephir_symbol_table *entry; zend_zephir_globals_def *gptr = ZEPHIR_VGLOBAL; - zend_execute_data *ex = EG(current_execute_data); zend_array *symbol_table; #ifndef ZEPHIR_RELEASE @@ -398,6 +413,15 @@ void zephir_create_symbol_table() } #endif + zend_execute_data* ex = find_symbol_table(EG(current_execute_data)); +#ifndef ZEPHIR_RELEASE + if (UNEXPECTED(!ex)) { + fprintf(stderr, "ERROR: unable to find a symbol table"); + zephir_print_backtrace(); + return; + } +#endif + zend_rebuild_symbol_table(); zend_detach_symbol_table(ex); diff --git a/ext/php_test.h b/ext/php_test.h index 16dd8b39b3..ed3a9ff8ea 100644 --- a/ext/php_test.h +++ b/ext/php_test.h @@ -14,7 +14,7 @@ #define PHP_TEST_VERSION "1.0.0" #define PHP_TEST_EXTNAME "test" #define PHP_TEST_AUTHOR "Zephir Team" -#define PHP_TEST_ZEPVERSION "0.11.4-$Id$" +#define PHP_TEST_ZEPVERSION "0.11.5-$Id$" #define PHP_TEST_DESCRIPTION "Description test for
Test Extension" typedef struct _zephir_struct_test { diff --git a/ext/test/requires.zep.c b/ext/test/requires.zep.c index 39b3809d89..203187d437 100644 --- a/ext/test/requires.zep.c +++ b/ext/test/requires.zep.c @@ -14,9 +14,11 @@ #include "kernel/main.h" #include "kernel/memory.h" #include "kernel/require.h" -#include "kernel/operators.h" #include "kernel/fcall.h" #include "kernel/object.h" +#include "ext/spl/spl_exceptions.h" +#include "kernel/exception.h" +#include "kernel/operators.h" ZEPHIR_INIT_CLASS(Test_Requires) { @@ -71,13 +73,12 @@ PHP_METHOD(Test_Requires, requireExternal2) { PHP_METHOD(Test_Requires, requireExternal3) { zend_long ZEPHIR_LAST_CALL_STATUS; - zval *path, path_sub, external3, _0, _1$$3; + zval *path, path_sub, external3, _0; zval *this_ptr = getThis(); ZVAL_UNDEF(&path_sub); ZVAL_UNDEF(&external3); ZVAL_UNDEF(&_0); - ZVAL_UNDEF(&_1$$3); ZEPHIR_MM_GROW(); zephir_fetch_params(1, 1, 0, &path); @@ -85,12 +86,8 @@ PHP_METHOD(Test_Requires, requireExternal3) { ZEPHIR_INIT_VAR(&_0); - ZEPHIR_GET_CONSTANT(&_0, "PHP_MAJOR_VERSION"); - if (ZEPHIR_IS_LONG(&_0, 5)) { - ZEPHIR_INIT_VAR(&_1$$3); - zephir_create_symbol_table(TSRMLS_C); - - } + zephir_create_symbol_table(TSRMLS_C); + ZEPHIR_INIT_VAR(&external3); object_init_ex(&external3, test_requires_external3_ce); if (zephir_has_constructor(&external3 TSRMLS_CC)) { @@ -118,3 +115,65 @@ PHP_METHOD(Test_Requires, setContent) { } +PHP_METHOD(Test_Requires, renderTemplate) { + + zend_string *_3$$3; + zend_ulong _2$$3; + zval *templatePath_param = NULL, *params, params_sub, _0, key, value, _5, *_1$$3, _4$$4; + zval templatePath; + zval *this_ptr = getThis(); + + ZVAL_UNDEF(&templatePath); + ZVAL_UNDEF(¶ms_sub); + ZVAL_UNDEF(&_0); + ZVAL_UNDEF(&key); + ZVAL_UNDEF(&value); + ZVAL_UNDEF(&_5); + ZVAL_UNDEF(&_4$$4); + + ZEPHIR_MM_GROW(); + zephir_fetch_params(1, 2, 0, &templatePath_param, ¶ms); + + if (UNEXPECTED(Z_TYPE_P(templatePath_param) != IS_STRING && Z_TYPE_P(templatePath_param) != IS_NULL)) { + zephir_throw_exception_string(spl_ce_InvalidArgumentException, SL("Parameter 'templatePath' must be a string") TSRMLS_CC); + RETURN_MM_NULL(); + } + if (EXPECTED(Z_TYPE_P(templatePath_param) == IS_STRING)) { + zephir_get_strval(&templatePath, templatePath_param); + } else { + ZEPHIR_INIT_VAR(&templatePath); + ZVAL_EMPTY_STRING(&templatePath); + } + + + ZEPHIR_INIT_VAR(&_0); + zephir_create_symbol_table(TSRMLS_C); + + if (Z_TYPE_P(params) == IS_ARRAY) { + zephir_is_iterable(params, 0, "test/requires.zep", 47); + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(params), _2$$3, _3$$3, _1$$3) + { + ZEPHIR_INIT_NVAR(&key); + if (_3$$3 != NULL) { + ZVAL_STR_COPY(&key, _3$$3); + } else { + ZVAL_LONG(&key, _2$$3); + } + ZEPHIR_INIT_NVAR(&value); + ZVAL_COPY(&value, _1$$3); + ZEPHIR_CPY_WRT(&_4$$4, &value); + if (zephir_set_symbol(&key, &_4$$4 TSRMLS_CC) == FAILURE) { + return; + } + } ZEND_HASH_FOREACH_END(); + ZEPHIR_INIT_NVAR(&value); + ZEPHIR_INIT_NVAR(&key); + } + ZEPHIR_OBSERVE_OR_NULLIFY_PPZV(&_5); + if (zephir_require_zval_ret(&_5, &templatePath TSRMLS_CC) == FAILURE) { + RETURN_MM_NULL(); + } + RETURN_CCTOR(&_5); + +} + diff --git a/ext/test/requires.zep.h b/ext/test/requires.zep.h index 66f6040dfb..29208e7d37 100644 --- a/ext/test/requires.zep.h +++ b/ext/test/requires.zep.h @@ -7,6 +7,7 @@ PHP_METHOD(Test_Requires, requireExternal1); PHP_METHOD(Test_Requires, requireExternal2); PHP_METHOD(Test_Requires, requireExternal3); PHP_METHOD(Test_Requires, setContent); +PHP_METHOD(Test_Requires, renderTemplate); ZEND_BEGIN_ARG_INFO_EX(arginfo_test_requires_requireexternal1, 0, 0, 1) ZEND_ARG_INFO(0, path) @@ -24,10 +25,16 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_test_requires_setcontent, 0, 0, 1) ZEND_ARG_INFO(0, content) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_test_requires_rendertemplate, 0, 0, 2) + ZEND_ARG_TYPE_INFO(0, templatePath, IS_STRING, 0) + ZEND_ARG_INFO(0, params) +ZEND_END_ARG_INFO() + ZEPHIR_INIT_FUNCS(test_requires_method_entry) { PHP_ME(Test_Requires, requireExternal1, arginfo_test_requires_requireexternal1, ZEND_ACC_PUBLIC) PHP_ME(Test_Requires, requireExternal2, arginfo_test_requires_requireexternal2, ZEND_ACC_PUBLIC) PHP_ME(Test_Requires, requireExternal3, arginfo_test_requires_requireexternal3, ZEND_ACC_PUBLIC) PHP_ME(Test_Requires, setContent, arginfo_test_requires_setcontent, ZEND_ACC_PUBLIC) + PHP_ME(Test_Requires, renderTemplate, arginfo_test_requires_rendertemplate, ZEND_ACC_PUBLIC) PHP_FE_END }; diff --git a/kernels/ZendEngine3/memory.c b/kernels/ZendEngine3/memory.c index 7de519e45b..1cb64ad6ed 100644 --- a/kernels/ZendEngine3/memory.c +++ b/kernels/ZendEngine3/memory.c @@ -45,6 +45,16 @@ * Not all methods must grow/restore the zephir_memory_entry. */ +static zend_always_inline zend_execute_data* +find_symbol_table(zend_execute_data* ex) +{ + while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) { + ex = ex->prev_execute_data; + } + + return ex; +} + static zephir_memory_entry* zephir_memory_grow_stack_common(zend_zephir_globals_def *g) { assert(g->start_memory != NULL); @@ -102,8 +112,14 @@ static void zephir_memory_restore_stack_common(zend_zephir_globals_def *g) if (g->active_symbol_table) { active_symbol_table = g->active_symbol_table; while (active_symbol_table && active_symbol_table->scope == active_memory) { - zend_execute_data *ex = EG(current_execute_data); - + zend_execute_data *ex = find_symbol_table(EG(current_execute_data)); +#ifndef ZEPHIR_RELEASE + if (UNEXPECTED(!ex)) { + fprintf(stderr, "ERROR: unable to find a symbol table"); + zephir_print_backtrace(); + return; + } +#endif zend_hash_destroy(ex->symbol_table); efree(ex->symbol_table); ex->symbol_table = active_symbol_table->symbol_table; @@ -387,7 +403,6 @@ void zephir_create_symbol_table() { zephir_symbol_table *entry; zend_zephir_globals_def *gptr = ZEPHIR_VGLOBAL; - zend_execute_data *ex = EG(current_execute_data); zend_array *symbol_table; #ifndef ZEPHIR_RELEASE @@ -398,6 +413,15 @@ void zephir_create_symbol_table() } #endif + zend_execute_data* ex = find_symbol_table(EG(current_execute_data)); +#ifndef ZEPHIR_RELEASE + if (UNEXPECTED(!ex)) { + fprintf(stderr, "ERROR: unable to find a symbol table"); + zephir_print_backtrace(); + return; + } +#endif + zend_rebuild_symbol_table(); zend_detach_symbol_table(ex); diff --git a/test/requires.zep b/test/requires.zep index 9de587fbc8..7ec3511be1 100644 --- a/test/requires.zep +++ b/test/requires.zep @@ -22,9 +22,7 @@ class Requires { var external3; - if PHP_MAJOR_VERSION == 5 { - create_symbol_table(); - } + create_symbol_table(); let external3 = new External3(); external3->req(path, this); @@ -35,4 +33,19 @@ class Requires { let this->content = content; } + + public function renderTemplate(string! templatePath, var params) -> var + { + create_symbol_table(); + + var key, value; + + if typeof params == "array" { + for key, value in params { + let {key} = value; + } + } + + return require templatePath; + } } diff --git a/unit-tests/Extension/Oo/ExtendClassTest.php b/unit-tests/Extension/Oo/ExtendClassTest.php index 4f4d44c1da..0ede9fe503 100644 --- a/unit-tests/Extension/Oo/ExtendClassTest.php +++ b/unit-tests/Extension/Oo/ExtendClassTest.php @@ -22,7 +22,7 @@ class ExtendClassTest extends TestCase public function testPDOExtending() { if (!extension_loaded('pdo')) { - $this->markTestSkipped('The PDO extendsion is not loaded'); + $this->markTestSkipped('The PDO extension is not loaded'); } $this->assertSame(PDO::getAvailableDrivers(), ExtendPdoClass::getAvailableDrivers()); diff --git a/unit-tests/Extension/RequiresTest.php b/unit-tests/Extension/RequiresTest.php index 7bda982ecb..384ecf8c04 100644 --- a/unit-tests/Extension/RequiresTest.php +++ b/unit-tests/Extension/RequiresTest.php @@ -30,7 +30,11 @@ public function testRequireExternal1() $this->assertTrue(defined('REQUIRE_ME')); } - public function testRequireExternal3() + /** + * @test + * @issue https://github.com/phalcon/zephir/pull/1428 + */ + public function shouldRequireUsingNewSymbolTable() { $r = new Requires(); @@ -40,6 +44,23 @@ public function testRequireExternal3() ); } + /** + * @test + * @issue https://github.com/phalcon/zephir/issues/1621 + */ + public function shouldRenderTemplate() + { + $r = new Requires(); + $a = 1; + + $this->assertEquals( + 2, + $r->renderTemplate(__DIR__ . '/../fixtures/template.php', ['a' => 2]) + ); + + $this->assertEquals(1, $a); + } + /** * @test * @issue https://github.com/phalcon/zephir/issues/1713 diff --git a/unit-tests/fixtures/template.php b/unit-tests/fixtures/template.php new file mode 100644 index 0000000000..482bd05433 --- /dev/null +++ b/unit-tests/fixtures/template.php @@ -0,0 +1,12 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +return $a;