static int zend_optimizer_lookup_cv(zend_op_array *op_array, char* name, int name_len) { int i = 0; ulong hash_value = zend_inline_hash_func(name, name_len+1); while (i < op_array->last_var) { if (op_array->vars[i].name == name || (op_array->vars[i].hash_value == hash_value && op_array->vars[i].name_len == name_len && memcmp(op_array->vars[i].name, name, name_len) == 0)) { return i; } i++; } i = op_array->last_var; op_array->last_var++; op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_compiled_variable)); if (IS_INTERNED(name)) { op_array->vars[i].name = name; } else { op_array->vars[i].name = estrndup(name, name_len); } op_array->vars[i].name_len = name_len; op_array->vars[i].hash_value = hash_value; return i; }
void copy_zend_constant(zend_constant *c) { if (!IS_INTERNED(c->name)) { c->name = zend_strndup(c->name, c->name_len - 1); } if (!(c->flags & CONST_PERSISTENT)) { zval_copy_ctor(&c->value); } }
static zend_always_inline zend_string *zend_clone_str(zend_string *str) { zend_string *ret; if (EXPECTED(IS_INTERNED(str))) { ret = str; } else if (GC_REFCOUNT(str) <= 1 || (ret = accel_xlat_get(str)) == NULL) { ret = zend_string_dup(str, 0); GC_FLAGS(ret) = GC_FLAGS(str); if (GC_REFCOUNT(str) > 1) { accel_xlat_set(str, ret); } } else { GC_REFCOUNT(ret)++; } return ret; }
static zval *phannot_ret_annotation(phannot_parser_token *name, zval *arguments, phannot_scanner_state *state) { zval *ret; MAKE_STD_ZVAL(ret); array_init_size(ret, 5); add_assoc_long(ret, "type", PHANNOT_T_ANNOTATION); if (name) { add_assoc_stringl(ret, "name", name->token, name->token_len, 0); efree(name); } if (arguments) { add_assoc_zval(ret, "arguments", arguments); } add_assoc_string(ret, "file", (char*)state->active_file, !IS_INTERNED(state->active_file)); add_assoc_long(ret, "line", state->active_line); return ret; }
ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC) { uint nIndex; Bucket *p; #ifdef ZEND_SIGNALS TSRMLS_FETCH(); #endif IS_CONSISTENT(ht); if (nKeyLength == 0) { return zend_hash_index_update(ht, h, pData, nDataSize, pDest); } CHECK_INIT(ht); nIndex = h & ht->nTableMask; p = ht->arBuckets[nIndex]; while (p != NULL) { if (p->arKey == arKey || ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { if (flag & HASH_ADD) { return FAILURE; } HANDLE_BLOCK_INTERRUPTIONS(); #if ZEND_DEBUG if (p->pData == pData) { ZEND_PUTS("Fatal error in zend_hash_update: p->pData == pData\n"); HANDLE_UNBLOCK_INTERRUPTIONS(); return FAILURE; } #endif if (ht->pDestructor) { ht->pDestructor(p->pData); } UPDATE_DATA(ht, p, pData, nDataSize); if (pDest) { *pDest = p->pData; } HANDLE_UNBLOCK_INTERRUPTIONS(); return SUCCESS; } p = p->pNext; } if (IS_INTERNED(arKey)) { p = (Bucket *) pemalloc(sizeof(Bucket), ht->persistent); if (!p) { return FAILURE; } p->arKey = arKey; } else { p = (Bucket *) pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent); if (!p) { return FAILURE; } p->arKey = (const char*)(p + 1); memcpy((char*)p->arKey, arKey, nKeyLength); } p->nKeyLength = nKeyLength; INIT_DATA(ht, p, pData, nDataSize); p->h = h; CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]); if (pDest) { *pDest = p->pData; } HANDLE_BLOCK_INTERRUPTIONS(); ht->arBuckets[nIndex] = p; CONNECT_TO_GLOBAL_DLLIST(p, ht); HANDLE_UNBLOCK_INTERRUPTIONS(); ht->nNumOfElements++; ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */ return SUCCESS; }
/** * Set the background color of an image. This is only useful for images * with alpha transparency. * * @param string $color hexadecimal color value * @param int $opacity background opacity: 0-100 * @return Phalcon\Image\Adapter */ PHP_METHOD(Phalcon_Image_Adapter, background) { zval *color, *opacity = NULL; zval *tmp_color = NULL, *r = NULL, *g = NULL, *b = NULL; long i; char *c; zval tmp; PHALCON_MM_GROW(); phalcon_fetch_params(1, 1, 1, &color, &opacity); if (Z_TYPE_P(color) != IS_STRING) { PHALCON_SEPARATE_PARAM(color); convert_to_string(color); } c = Z_STRVAL_P(color); if (Z_STRLEN_P(color) > 0 && c[0] == '#') { PHALCON_INIT_NVAR(tmp_color); phalcon_substr(tmp_color, color, 1, 0); } else { PHALCON_CPY_WRT_CTOR(tmp_color, color); } if (Z_STRLEN_P(tmp_color) == 3) { /* Convert RGB to RRGGBB */ c = Z_STRVAL_P(tmp_color); if (!IS_INTERNED(c)) { STR_REALLOC(c, 7); } else { char* tmp = ecalloc(7, 1); memcpy(tmp, c, Z_STRLEN_P(tmp_color)); c = tmp; } c[6] = '\0'; c[5] = c[2]; c[4] = c[2]; c[3] = c[1]; c[2] = c[1]; c[1] = c[0]; ZVAL_STRING(tmp_color, c, 0); } if (Z_STRLEN_P(tmp_color) < 6) { PHALCON_THROW_EXCEPTION_STR(phalcon_image_exception_ce, "Color is not valid"); return; } INIT_ZVAL(tmp); Z_TYPE(tmp) = IS_STRING; ZVAL_STRINGL(&tmp, Z_STRVAL_P(tmp_color), 2, 0); PHALCON_INIT_NVAR(r); _php_math_basetozval(&tmp, 16, r); Z_STRVAL(tmp) += 2; PHALCON_INIT_NVAR(g); _php_math_basetozval(&tmp, 16, g); Z_STRVAL(tmp) += 2; PHALCON_INIT_NVAR(b); _php_math_basetozval(&tmp, 16, b); if (!opacity) { PHALCON_INIT_NVAR(opacity); ZVAL_LONG(opacity, 100); } else { PHALCON_SEPARATE_PARAM(opacity); i = phalcon_get_intval(opacity); if (i < 1) { PHALCON_INIT_NVAR(opacity); ZVAL_LONG(opacity, 1); } else if (i > 100) { PHALCON_INIT_NVAR(opacity); ZVAL_LONG(opacity, 100); } } PHALCON_CALL_METHOD(NULL, this_ptr, "_background", r, g, b, opacity); RETURN_THIS(); }
/** * Add a text to an image with a specified opacity. * * @param string text * @param int $offset_x offset from the left, If less than 0 offset from the right, If true right the x offset * @param int $offset_y offset from the top, If less than 0 offset from the bottom, If true bottom the Y offset * @param int $opacity opacity of text: 1-100 * @param string $color hexadecimal color value * @param int $size font pointsize * @param string $fontfile font path * @return Phalcon\Image\Adapter */ PHP_METHOD(Phalcon_Image_Adapter, text) { zval **text, **ofs_x = NULL, **ofs_y = NULL, **op = NULL, **fontcolor = NULL, **fontsize = NULL, **fontfile = NULL; zval *offset_x = NULL, *offset_y = NULL, *opacity, *color, *size; zval *r, *g, *b; char *c; zval tmp; phalcon_fetch_params_ex(1, 6, &text, &ofs_x, &ofs_y, &op, &fontcolor, &fontsize, &fontfile); PHALCON_MM_GROW(); if (!ofs_x || Z_TYPE_PP(ofs_x) == IS_NULL) { PHALCON_INIT_VAR(offset_x); ZVAL_FALSE(offset_x); } else { PHALCON_CPY_WRT_CTOR(offset_x, *ofs_x); } if (!ofs_y || Z_TYPE_PP(ofs_y) == IS_NULL) { PHALCON_INIT_VAR(offset_y); ZVAL_FALSE(offset_y); } else { PHALCON_CPY_WRT_CTOR(offset_y, *ofs_y); } PHALCON_INIT_VAR(opacity); if (!op || Z_TYPE_PP(op) == IS_NULL) { ZVAL_LONG(opacity, 100); } else { PHALCON_ENSURE_IS_LONG(op); if (Z_LVAL_PP(op) < 1) { ZVAL_LONG(opacity, 1); } else if (Z_LVAL_PP(op) > 100) { ZVAL_LONG(opacity, 100); } else { ZVAL_LONG(opacity, Z_LVAL_PP(op)); } } PHALCON_INIT_VAR(color); if (!fontcolor || Z_TYPE_PP(fontcolor) == IS_NULL) { ZVAL_STRING(color, "000000", 1); } else { PHALCON_ENSURE_IS_STRING(fontcolor); if (Z_STRLEN_PP(fontcolor) > 1 && Z_STRVAL_PP(fontcolor)[0] == '#') { phalcon_substr(color, *fontcolor, 1, 0); } else { ZVAL_STRINGL(color, Z_STRVAL_PP(fontcolor), Z_STRLEN_PP(fontcolor), 1); } } PHALCON_INIT_VAR(size); if (!fontsize || Z_TYPE_PP(fontsize) == IS_NULL) { ZVAL_LONG(size, 12); } else { PHALCON_ENSURE_IS_LONG(fontsize); ZVAL_LONG(size, Z_LVAL_PP(fontsize)); } if (!fontfile) { fontfile = &PHALCON_GLOBAL(z_null); } if (Z_STRLEN_P(color) == 3) { /* Convert RGB to RRGGBB */ c = Z_STRVAL_P(color); assert(!IS_INTERNED(c)); STR_REALLOC(c, 7); c[6] = '\0'; c[5] = c[2]; c[4] = c[2]; c[3] = c[1]; c[2] = c[1]; c[1] = c[0]; ZVAL_STRING(color, c, 0); } if (Z_STRLEN_P(color) < 6) { PHALCON_THROW_EXCEPTION_STR(phalcon_image_exception_ce, "color is not valid"); return; } INIT_ZVAL(tmp); Z_TYPE(tmp) = IS_STRING; ZVAL_STRINGL(&tmp, Z_STRVAL_P(color), 2, 0); PHALCON_INIT_VAR(r); _php_math_basetozval(&tmp, 16, r); Z_STRVAL(tmp) += 2; PHALCON_INIT_VAR(g); _php_math_basetozval(&tmp, 16, g); Z_STRVAL(tmp) += 2; PHALCON_INIT_VAR(b); _php_math_basetozval(&tmp, 16, b); PHALCON_CALL_METHOD(NULL, this_ptr, "_text", *text, offset_x, offset_y, opacity, r, g, b, size, *fontfile); RETURN_THIS(); }
static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC) { #ifndef ZTS ulong h; uint nIndex; Bucket *p; if (IS_INTERNED(arKey)) { return arKey; } h = zend_inline_hash_func(arKey, nKeyLength); nIndex = h & CG(interned_strings).nTableMask; p = CG(interned_strings).arBuckets[nIndex]; while (p != NULL) { if ((p->h == h) && (p->nKeyLength == nKeyLength)) { if (!memcmp(p->arKey, arKey, nKeyLength)) { if (free_src) { efree((void *)arKey); } return p->arKey; } } p = p->pNext; } if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >= CG(interned_strings_end)) { /* no memory */ return arKey; } p = (Bucket *) CG(interned_strings_top); CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength); #if ZEND_DEBUG_INTERNED_STRINGS mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE); #endif p->arKey = (char*)(p+1); memcpy((char*)p->arKey, arKey, nKeyLength); if (free_src) { efree((void *)arKey); } p->nKeyLength = nKeyLength; p->h = h; p->pData = &p->pDataPtr; p->pDataPtr = p; p->pNext = CG(interned_strings).arBuckets[nIndex]; p->pLast = NULL; if (p->pNext) { p->pNext->pLast = p; } HANDLE_BLOCK_INTERRUPTIONS(); p->pListLast = CG(interned_strings).pListTail; CG(interned_strings).pListTail = p; p->pListNext = NULL; if (p->pListLast != NULL) { p->pListLast->pListNext = p; } if (!CG(interned_strings).pListHead) { CG(interned_strings).pListHead = p; } CG(interned_strings).arBuckets[nIndex] = p; HANDLE_UNBLOCK_INTERRUPTIONS(); CG(interned_strings).nNumOfElements++; if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) { if ((CG(interned_strings).nTableSize << 1) > 0) { /* Let's double the table size */ Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent); if (t) { HANDLE_BLOCK_INTERRUPTIONS(); CG(interned_strings).arBuckets = t; CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1); CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1; zend_hash_rehash(&CG(interned_strings)); HANDLE_UNBLOCK_INTERRUPTIONS(); } } } #if ZEND_DEBUG_INTERNED_STRINGS mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ); #endif return p->arKey; #else return arKey; #endif }
/* 插入新值到哈希表中 */ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC) { ulong h; uint nIndex; Bucket *p; #ifdef ZEND_SIGNALS TSRMLS_FETCH(); #endif IS_CONSISTENT(ht); /* 键值不能为空字符串 */ if (nKeyLength <= 0) { #if ZEND_DEBUG ZEND_PUTS("zend_hash_update: Can't put in empty key\n"); #endif return FAILURE; } /* 检查哈希表是否以及初始化,如果没有初始化则进行初始化 */ CHECK_INIT(ht); /* 计算key代表的哈希值以及获取其在arBuckets数组中的下标 */ h = zend_inline_hash_func(arKey, nKeyLength); nIndex = h & ht->nTableMask; p = ht->arBuckets[nIndex]; while (p != NULL) { if (p->arKey == arKey || ((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) { /* 需要更新 */ if (flag & HASH_ADD) { /* 如果是插入的话就返回,不能插入具有相同键值的元素 */ return FAILURE; } HANDLE_BLOCK_INTERRUPTIONS(); #if ZEND_DEBUG if (p->pData == pData) { ZEND_PUTS("Fatal error in zend_hash_update: " "p->pData == pData\n"); HANDLE_UNBLOCK_INTERRUPTIONS(); return FAILURE; } #endif if (ht->pDestructor) { /* 如果有析构函数,则将指向数据的指针释放掉 */ ht->pDestructor(p->pData); } /* 更新数据 */ UPDATE_DATA(ht, p, pData, nDataSize); if (pDest) { *pDest = p->pData; } HANDLE_UNBLOCK_INTERRUPTIONS(); return SUCCESS; } /* 移动到具有相同hash值的bucket链表中的下一个bucket */ p = p->pNext; } if (IS_INTERNED(arKey)) { p = (Bucket *)pemalloc(sizeof(Bucket), ht->persistent); if (!p) { return FAILURE; } p->arKey = arKey; } else { p = (Bucket *)pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent); if (!p) { return FAILURE; } p->arKey = (const char *)(p + 1); memcpy((char *)p->arKey, arKey, nKeyLength); } /* 设置新的bucket的属性值及添加到哈希表中 */ p->nKeyLength = nKeyLength; INIT_DATA(ht, p, pData, nDataSize); p->h = h; CONNECT_TO_BUCKET_DLLIST(p, ht->arBuckets[nIndex]); if (pDest) { *pDest = p->pData; } HANDLE_BLOCK_INTERRUPTIONS(); CONNECT_TO_GLOBAL_DLLIST(p, ht); ht->arBuckets[nIndex] = p; HANDLE_UNBLOCK_INTERRUPTIONS(); ht->nNumOfElements++; ZEND_HASH_IF_FULL_DO_RESIZE( ht); /* If the Hash table is full, resize it */ return SUCCESS; }
static void dic_optimizer_get_handler(INTERNAL_FUNCTION_PARAMETERS) { char *id, should_free = 1; zend_ulong id_hash; int id_len, i; long oninvalid, exception_on_invalid_reference_const; zval **found_service, **alias, **method_in_map = NULL, *this_services, *this_aliases, *this_methodMap, *this_loading; zend_function *method = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &id, &id_len, &oninvalid) == FAILURE) { return; } if (strcasecmp(id, "service_container") == 0) { RETURN_THIS; } this_services = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_SERVICES_KEY, sizeof(SYMFONY_DIC_TOKEN_SERVICES_KEY) - 1, 0 TSRMLS_CC); this_aliases = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_ALIASES_KEY, sizeof(SYMFONY_DIC_TOKEN_ALIASES_KEY) - 1, 0 TSRMLS_CC); this_loading = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_LOADING_KEY, sizeof(SYMFONY_DIC_TOKEN_LOADING_KEY) - 1, 0 TSRMLS_CC); this_methodMap = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_METHODMAP_KEY, sizeof(SYMFONY_DIC_TOKEN_METHODMAP_KEY) - 1, 0 TSRMLS_CC); if (!SYMFONY_DIC_G(cache_done)) { zval invalidBehavior; zend_class_entry **exception_ce; zend_get_constant_ex("self::EXCEPTION_ON_INVALID_REFERENCE", sizeof("self::EXCEPTION_ON_INVALID_REFERENCE") - 1, &invalidBehavior, Z_OBJCE_P(getThis()), 0 TSRMLS_CC); SYMFONY_DIC_G(invalid_behavior) = Z_LVAL(invalidBehavior); if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) { zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP); } SYMFONY_DIC_G(ServiceCircularReferenceException) = *exception_ce; if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) { zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP); } SYMFONY_DIC_G(ServiceNotFoundException) = *exception_ce; if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) { zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP); } SYMFONY_DIC_G(InactiveScopeException) = *exception_ce; SYMFONY_DIC_G(cache_done) = 1; } exception_on_invalid_reference_const = SYMFONY_DIC_G(invalid_behavior); if (ZEND_NUM_ARGS() <= 1) { oninvalid = exception_on_invalid_reference_const; } if (IS_INTERNED(id)) { id_hash = INTERNED_HASH(id); } else { id_hash = zend_inline_hash_func(id, id_len + 1); } id = estrndup(id, id_len); /* zend_str_tolower will change it otherwise */ for (i = 0; i <= 1; i++, zend_str_tolower(id, id_len), id_hash = zend_inline_hash_func(id, id_len + 1)) { if (zend_hash_quick_find(Z_ARRVAL_P(this_aliases), id, id_len + 1, id_hash, (void **)&alias) == SUCCESS) { should_free = 0; efree(id); id = Z_STRVAL_PP(alias); id_len = Z_STRLEN_PP(alias); id_hash = zend_inline_hash_func(id, id_len + 1); } if (zend_hash_quick_find(Z_ARRVAL_P(this_services), id, id_len + 1, id_hash, (void **)&found_service) == SUCCESS) { RETVAL_ZVAL_FAST(*found_service); goto free_and_return; } } if (zend_hash_quick_exists(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash)) { zval *ServiceCircularReferenceException; ALLOC_INIT_ZVAL(ServiceCircularReferenceException); /* ctor_args */ object_init_ex(ServiceCircularReferenceException, SYMFONY_DIC_G(ServiceCircularReferenceException)); zend_throw_exception_object(ServiceCircularReferenceException TSRMLS_CC); goto free_and_return; } zend_hash_quick_find(Z_ARRVAL_P(this_methodMap), id, id_len + 1, id_hash, (void **)&method_in_map); if (!method_in_map) { char *new_id; for (i=0; i < id_len; i++) { if (id[i] == '_') { memmove(&id[i], &id[i + 1], --id_len); } } php_strtr(id, id_len, ".\\", "__", 2); id_len = spprintf(&new_id, 0, "get%sservice", id); efree(id); id = new_id; id_hash = zend_inline_hash_func(id, id_len + 1); zend_hash_quick_find(&Z_OBJCE_P(getThis())->function_table, id, id_len + 1, id_hash, (void **)&method); if (!method) { if (oninvalid == exception_on_invalid_reference_const) { zval *ServiceNotFoundException; ALLOC_INIT_ZVAL(ServiceNotFoundException); object_init_ex(ServiceNotFoundException, SYMFONY_DIC_G(ServiceNotFoundException)); zend_throw_exception_object(ServiceNotFoundException TSRMLS_CC); /* ctor_args */ } goto free_and_return; } } else { char *method_name_lc; method_name_lc = zend_str_tolower_dup(Z_STRVAL_PP(method_in_map), Z_STRLEN_PP(method_in_map)); zend_hash_find(&Z_OBJCE_P(getThis())->function_table, method_name_lc, Z_STRLEN_PP(method_in_map) + 1, (void **)&method); efree(method_name_lc); } zend_fcall_info fci = {0}; zend_fcall_info_cache fcic = {0}; zval *loading, *result; ALLOC_INIT_ZVAL(loading); ZVAL_BOOL(loading, 1); zend_hash_quick_add(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash, &loading, sizeof(zval *), NULL); fcic.called_scope = Z_OBJCE_P(getThis()); fcic.calling_scope = Z_OBJCE_P(getThis()); fcic.function_handler = method; fcic.initialized = 1; fcic.object_ptr = getThis(); fci.retval_ptr_ptr = &result; fci.size = sizeof(zend_fcall_info); zend_call_function(&fci, &fcic TSRMLS_CC); zend_hash_quick_del(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash); if (!EG(exception)) { RETVAL_ZVAL_FAST(result); } else { zend_hash_quick_del(Z_ARRVAL_P(this_services), id, id_len, id_hash); if (instanceof_function(Z_OBJCE_P(EG(exception)), SYMFONY_DIC_G(InactiveScopeException) TSRMLS_CC) && oninvalid == exception_on_invalid_reference_const) { EG(exception) = NULL; } } zval_ptr_dtor(&result); free_and_return: if (should_free) { efree(id); } return; }
/** * Produces an string representation of a variable * * @param mixed $variable * @return string */ PHP_METHOD(Phalcon_Debug, _getVarDump){ zval *variable, *class_name, *dumped_object = NULL; zval *array_dump = NULL, *dump = NULL; PHALCON_MM_GROW(); phalcon_fetch_params(1, 1, 0, &variable); if (PHALCON_IS_SCALAR(variable)) { /** * Boolean variables are represented as 'true'/'false' */ if (Z_TYPE_P(variable) == IS_BOOL) { if (zend_is_true(variable)) { RETURN_MM_STRING("true", 1); } else { RETURN_MM_STRING("false", 1); } } /** * String variables are escaped to avoid XSS injections */ if (Z_TYPE_P(variable) == IS_STRING) { PHALCON_RETURN_CALL_METHOD(this_ptr, "_escapestring", variable); RETURN_MM(); } /** * Other scalar variables are just converted to strings */ RETURN_CTOR(variable); } /** * If the variable is an object print its class name */ if (Z_TYPE_P(variable) == IS_OBJECT) { const zend_class_entry *ce = Z_OBJCE_P(variable); PHALCON_INIT_VAR(class_name); ZVAL_STRINGL(class_name, ce->name, ce->name_length, !IS_INTERNED(ce->name)); /** * Try to check for a 'dump' method, this surely produces a better printable * representation */ if (phalcon_method_exists_ex(variable, SS("dump") TSRMLS_CC) == SUCCESS) { PHALCON_CALL_METHOD(&dumped_object, variable, "dump"); /** * dump() must return an array, generate a recursive representation using * getArrayDump */ PHALCON_CALL_METHOD(&array_dump, this_ptr, "_getarraydump", dumped_object); PHALCON_INIT_VAR(dump); PHALCON_CONCAT_SVSVS(dump, "Object(", class_name, ": ", array_dump, ")"); } else { /** * If dump() is not available just print the class name */ PHALCON_INIT_NVAR(dump); PHALCON_CONCAT_SVS(dump, "Object(", class_name, ")</span>"); } RETURN_CTOR(dump); } /** * Recursively process the array and enclose it in Array() */ if (Z_TYPE_P(variable) == IS_ARRAY) { PHALCON_CALL_METHOD(&array_dump, this_ptr, "_getarraydump", variable); PHALCON_CONCAT_SVS(return_value, "Array(", array_dump, ")"); RETURN_MM(); } /** * Null variables are represented as 'null' * Other types are represented by its type */ RETURN_MM_STRING(zend_zval_type_name(variable), 1); }
/** * Produces a recursive representation of an array * * @param array $argument * @return string */ PHP_METHOD(Phalcon_Debug, _getArrayDump){ zval *argument, *n = NULL, *number_arguments, *dump; zval *v = NULL, *k = NULL, *var_dump = NULL, *escaped_string = NULL, *next = NULL, *array_dump = NULL; zval *class_name = NULL, *joined_dump; HashTable *ah0; HashPosition hp0; zval **hd; PHALCON_MM_GROW(); phalcon_fetch_params(1, 1, 1, &argument, &n); if (!n) { PHALCON_INIT_VAR(n); ZVAL_LONG(n, 0); } PHALCON_INIT_VAR(number_arguments); phalcon_fast_count(number_arguments, argument TSRMLS_CC); if (PHALCON_LT_LONG(n, 3)) { if (PHALCON_GT_LONG(number_arguments, 0)) { if (PHALCON_LT_LONG(number_arguments, 10)) { PHALCON_INIT_VAR(dump); array_init(dump); phalcon_is_iterable(argument, &ah0, &hp0, 0, 0); while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) { PHALCON_GET_HKEY(k, ah0, hp0); PHALCON_GET_HVALUE(v); if (PHALCON_IS_SCALAR(v)) { if (PHALCON_IS_STRING(v, "")) { PHALCON_INIT_NVAR(var_dump); PHALCON_CONCAT_SVS(var_dump, "[", k, "] => (empty string)"); } else { PHALCON_CALL_METHOD(&escaped_string, this_ptr, "_escapestring", v); PHALCON_INIT_NVAR(var_dump); PHALCON_CONCAT_SVSV(var_dump, "[", k, "] => ", escaped_string); } phalcon_array_append(&dump, var_dump, PH_COPY); } else { if (Z_TYPE_P(v) == IS_ARRAY) { PHALCON_INIT_NVAR(next); phalcon_add_function(next, n, PHALCON_GLOBAL(z_one)); PHALCON_CALL_METHOD(&array_dump, this_ptr, "_getarraydump", v, next); PHALCON_INIT_NVAR(var_dump); PHALCON_CONCAT_SVSVS(var_dump, "[", k, "] => Array(", array_dump, ")"); phalcon_array_append(&dump, var_dump, PH_COPY); zend_hash_move_forward_ex(ah0, &hp0); continue; } if (Z_TYPE_P(v) == IS_OBJECT) { zend_class_entry *ce = Z_OBJCE_P(v); PHALCON_INIT_NVAR(class_name); ZVAL_STRINGL(class_name, ce->name, ce->name_length, !IS_INTERNED(ce->name)); PHALCON_INIT_NVAR(var_dump); PHALCON_CONCAT_SVSVS(var_dump, "[", k, "] => Object(", class_name, ")"); phalcon_array_append(&dump, var_dump, PH_COPY); zend_hash_move_forward_ex(ah0, &hp0); continue; } if (Z_TYPE_P(v) == IS_NULL) { PHALCON_INIT_NVAR(var_dump); PHALCON_CONCAT_SVS(var_dump, "[", k, "] => null"); phalcon_array_append(&dump, var_dump, PH_COPY); zend_hash_move_forward_ex(ah0, &hp0); continue; } PHALCON_INIT_NVAR(var_dump); PHALCON_CONCAT_SVSV(var_dump, "[", k, "] => ", v); phalcon_array_append(&dump, var_dump, PH_COPY); } zend_hash_move_forward_ex(ah0, &hp0); } PHALCON_INIT_VAR(joined_dump); phalcon_fast_join_str(joined_dump, SL(", "), dump TSRMLS_CC); RETURN_CTOR(joined_dump); } RETURN_NCTOR(number_arguments); } } RETURN_MM_NULL(); }
/** * Handles uncaught exceptions * * @param \Exception $exception * @return boolean */ PHP_METHOD(Phalcon_Debug, onUncaughtException){ zval *exception, *is_active = NULL, *message = NULL; zval *class_name, *css_sources = NULL, *escaped_message = NULL; zval *html, *version = NULL, *file = NULL, *line = NULL, *show_back_trace; zval *data_vars, *trace = NULL, *trace_item = NULL, *n = NULL, *html_item = NULL; zval *_REQUEST, *value = NULL, *key_request = NULL, *joined_value = NULL, *_SERVER; zval *key_server = NULL, *files = NULL, *key_file = NULL; zval *memory, *data_var = NULL, *key_var = NULL, *variable = NULL, *dumped_argument = NULL; zval *js_sources = NULL, *formatted_file = NULL; HashTable *ah0, *ah1, *ah2, *ah3, *ah4; HashPosition hp0, hp1, hp2, hp3, hp4; zval **hd; char* link_format; zend_bool ini_exists = 1; zval z_link_format = zval_used_for_init; zend_class_entry *ce; PHALCON_MM_GROW(); phalcon_fetch_params(1, 1, 0, &exception); PHALCON_VERIFY_CLASS_EX(exception, zend_exception_get_default(TSRMLS_C), phalcon_exception_ce, 1); /** * Cancel the output buffer if active */ if (phalcon_ob_get_level(TSRMLS_C) > 0) { phalcon_ob_end_clean(TSRMLS_C); } is_active = phalcon_fetch_static_property_ce(phalcon_debug_ce, SL("_isActive") TSRMLS_CC); /** * Avoid that multiple exceptions being showed */ if (zend_is_true(is_active)) { PHALCON_CALL_METHOD(&message, exception, "getmessage"); zend_print_zval(message, 0); } /** * Globally block the debug component to avoid other exceptions must be shown */ zend_update_static_property_bool(phalcon_debug_ce, SL("_isActive"), 1 TSRMLS_CC); PHALCON_INIT_VAR(class_name); ce = Z_OBJCE_P(exception); ZVAL_STRINGL(class_name, ce->name, ce->name_length, !IS_INTERNED(ce->name)); PHALCON_CALL_METHOD(&message, exception, "getmessage"); /** * CSS static sources to style the error presentation */ PHALCON_CALL_METHOD(&css_sources, this_ptr, "getcsssources"); /** * Escape the exception's message avoiding possible XSS injections? */ PHALCON_CPY_WRT(escaped_message, message); /** * Use the exception info as document's title */ PHALCON_INIT_VAR(html); PHALCON_CONCAT_SVSVS(html, "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><title>", class_name, ": ", escaped_message, "</title>"); PHALCON_SCONCAT_VS(html, css_sources, "</head><body>"); /** * Get the version link */ PHALCON_CALL_METHOD(&version, this_ptr, "getversion"); phalcon_concat_self(&html, version TSRMLS_CC); PHALCON_CALL_METHOD(&file, exception, "getfile"); PHALCON_CALL_METHOD(&line, exception, "getline"); link_format = zend_ini_string_ex(SS("xdebug.file_link_format"), 0, &ini_exists); if (!link_format || !ini_exists || !strlen(link_format)) { link_format = "file://%f#%l"; } ZVAL_STRING(&z_link_format, link_format, 0); PHALCON_CALL_METHOD(&formatted_file, getThis(), "getfilelink", file, line, &z_link_format); /** * Main exception info */ phalcon_concat_self_str(&html, SL("<div align=\"center\"><div class=\"error-main\">") TSRMLS_CC); PHALCON_SCONCAT_SVSVS(html, "<h1>", class_name, ": ", escaped_message, "</h1>"); PHALCON_SCONCAT_SVSVS(html, "<span class=\"error-file\">", formatted_file, " (", line, ")</span>"); phalcon_concat_self_str(&html, SL("</div>") TSRMLS_CC); PHALCON_OBS_VAR(show_back_trace); phalcon_read_property_this(&show_back_trace, this_ptr, SL("_showBackTrace"), PH_NOISY TSRMLS_CC); /** * Check if the developer wants to show the backtrace or not */ if (zend_is_true(show_back_trace)) { PHALCON_OBS_VAR(data_vars); phalcon_read_property_this(&data_vars, this_ptr, SL("_data"), PH_NOISY TSRMLS_CC); /** * Create the tabs in the page */ phalcon_concat_self_str(&html, SL("<div class=\"error-info\"><div id=\"tabs\"><ul>") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<li><a href=\"#error-tabs-1\">Backtrace</a></li>") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<li><a href=\"#error-tabs-2\">Request</a></li>") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<li><a href=\"#error-tabs-3\">Server</a></li>") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<li><a href=\"#error-tabs-4\">Included Files</a></li>") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<li><a href=\"#error-tabs-5\">Memory</a></li>") TSRMLS_CC); if (Z_TYPE_P(data_vars) == IS_ARRAY) { phalcon_concat_self_str(&html, SL("<li><a href=\"#error-tabs-6\">Variables</a></li>") TSRMLS_CC); } phalcon_concat_self_str(&html, SL("</ul>") TSRMLS_CC); /** * Print backtrace */ phalcon_concat_self_str(&html, SL("<div id=\"error-tabs-1\"><table cellspacing=\"0\" align=\"center\" width=\"100%\">") TSRMLS_CC); PHALCON_CALL_METHOD(&trace, exception, "gettrace"); phalcon_is_iterable(trace, &ah0, &hp0, 0, 0); while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) { PHALCON_GET_HKEY(n, ah0, hp0); PHALCON_GET_HVALUE(trace_item); /** * Every line in the trace is rendered using 'showTraceItem' */ PHALCON_CALL_METHOD(&html_item, this_ptr, "showtraceitem", n, trace_item, &z_link_format); phalcon_concat_self(&html, html_item TSRMLS_CC); zend_hash_move_forward_ex(ah0, &hp0); } phalcon_concat_self_str(&html, SL("</table></div>") TSRMLS_CC); /** * Print _REQUEST superglobal */ phalcon_concat_self_str(&html, SL("<div id=\"error-tabs-2\"><table cellspacing=\"0\" align=\"center\" class=\"superglobal-detail\">") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<tr><th>Key</th><th>Value</th></tr>") TSRMLS_CC); _REQUEST = phalcon_get_global(SS("_REQUEST") TSRMLS_CC); if (Z_TYPE_P(_REQUEST) == IS_ARRAY) { phalcon_is_iterable(_REQUEST, &ah1, &hp1, 0, 0); while (zend_hash_get_current_data_ex(ah1, (void**) &hd, &hp1) == SUCCESS) { PHALCON_GET_HKEY(key_request, ah1, hp1); PHALCON_GET_HVALUE(value); if (Z_TYPE_P(value) == IS_ARRAY) { PHALCON_CALL_METHOD(&joined_value, this_ptr, "_getvardump", value); PHALCON_SCONCAT_SVSVS(html, "<tr><td class=\"key\">", key_request, "</td><td>", joined_value, "</td></tr>"); } else { PHALCON_SCONCAT_SVSVS(html, "<tr><td class=\"key\">", key_request, "</td><td>", value, "</td></tr>"); } zend_hash_move_forward_ex(ah1, &hp1); } } phalcon_concat_self_str(&html, SL("</table></div>") TSRMLS_CC); /** * Print _SERVER superglobal */ phalcon_concat_self_str(&html, SL("<div id=\"error-tabs-3\"><table cellspacing=\"0\" align=\"center\" class=\"superglobal-detail\">") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<tr><th>Key</th><th>Value</th></tr>") TSRMLS_CC); _SERVER = phalcon_get_global(SS("_SERVER") TSRMLS_CC); if (Z_TYPE_P(_SERVER) == IS_ARRAY) { phalcon_is_iterable(_SERVER, &ah2, &hp2, 0, 0); while (zend_hash_get_current_data_ex(ah2, (void**) &hd, &hp2) == SUCCESS) { PHALCON_GET_HKEY(key_server, ah2, hp2); PHALCON_GET_HVALUE(value); PHALCON_CALL_METHOD(&dumped_argument, this_ptr, "_getvardump", value); PHALCON_SCONCAT_SVSVS(html, "<tr><td class=\"key\">", key_server, "</td><td>", dumped_argument, "</td></tr>"); zend_hash_move_forward_ex(ah2, &hp2); } } phalcon_concat_self_str(&html, SL("</table></div>") TSRMLS_CC); /** * Show included files */ PHALCON_CALL_FUNCTION(&files, "get_included_files"); phalcon_concat_self_str(&html, SL("<div id=\"error-tabs-4\"><table cellspacing=\"0\" align=\"center\" class=\"superglobal-detail\">") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<tr><th>#</th><th>Path</th></tr>") TSRMLS_CC); phalcon_is_iterable(files, &ah3, &hp3, 0, 0); while (zend_hash_get_current_data_ex(ah3, (void**) &hd, &hp3) == SUCCESS) { PHALCON_GET_HKEY(key_file, ah3, hp3); PHALCON_GET_HVALUE(value); PHALCON_SCONCAT_SVSVS(html, "<tr><td>", key_file, "</th><td>", value, "</td></tr>"); zend_hash_move_forward_ex(ah3, &hp3); } phalcon_concat_self_str(&html, SL("</table></div>") TSRMLS_CC); /** * Memory usage */ PHALCON_INIT_VAR(memory); ZVAL_LONG(memory, zend_memory_usage(1 TSRMLS_CC)); phalcon_concat_self_str(&html, SL("<div id=\"error-tabs-5\"><table cellspacing=\"0\" align=\"center\" class=\"superglobal-detail\">") TSRMLS_CC); PHALCON_SCONCAT_SVS(html, "<tr><th colspan=\"2\">Memory</th></tr><tr><td>Usage</td><td>", memory, "</td></tr>"); phalcon_concat_self_str(&html, SL("</table></div>") TSRMLS_CC); /** * Print extra variables passed to the component */ if (Z_TYPE_P(data_vars) == IS_ARRAY) { phalcon_concat_self_str(&html, SL("<div id=\"error-tabs-6\"><table cellspacing=\"0\" align=\"center\" class=\"superglobal-detail\">") TSRMLS_CC); phalcon_concat_self_str(&html, SL("<tr><th>Key</th><th>Value</th></tr>") TSRMLS_CC); phalcon_is_iterable(data_vars, &ah4, &hp4, 0, 0); while (zend_hash_get_current_data_ex(ah4, (void**) &hd, &hp4) == SUCCESS) { PHALCON_GET_HKEY(key_var, ah4, hp4); PHALCON_GET_HVALUE(data_var); PHALCON_OBS_NVAR(variable); phalcon_array_fetch_long(&variable, data_var, 0, PH_NOISY); PHALCON_CALL_METHOD(&dumped_argument, this_ptr, "_getvardump", variable); PHALCON_SCONCAT_SVSVS(html, "<tr><td class=\"key\">", key_var, "</td><td>", dumped_argument, "</td></tr>"); zend_hash_move_forward_ex(ah4, &hp4); } phalcon_concat_self_str(&html, SL("</table></div>") TSRMLS_CC); } phalcon_concat_self_str(&html, SL("</div>") TSRMLS_CC); } /** * Get Javascript sources */ PHALCON_CALL_METHOD(&js_sources, this_ptr, "getjssources"); PHALCON_SCONCAT_VS(html, js_sources, "</div></body></html>"); /** * Print the HTML, @TODO, add an option to store the html */ zend_print_zval(html, 0); /** * Unlock the exception renderer */ zend_update_static_property_bool(phalcon_debug_ce, SL("_isActive"), 0 TSRMLS_CC); RETURN_MM_TRUE; }