Пример #1
0
/**
 * Updates values on arrays by string indexes only with a pre-calculated hash
 */
int phalcon_array_update_quick_string(zval **arr, char *index, uint index_length, unsigned long key, zval **value, int flags TSRMLS_DC){

	if (unlikely(Z_TYPE_PP(arr) != IS_ARRAY)) {
		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
		return FAILURE;
	}

	if ((flags & PH_CTOR) == PH_CTOR) {
		zval *new_zv;
		Z_DELREF_PP(value);
		ALLOC_ZVAL(new_zv);
		INIT_PZVAL_COPY(new_zv, *value);
		*value = new_zv;
		zval_copy_ctor(new_zv);
	}

	if ((flags & PH_SEPARATE) == PH_SEPARATE) {
		if (Z_REFCOUNT_PP(arr) > 1) {
			zval *new_zv;
			Z_DELREF_PP(arr);
			ALLOC_ZVAL(new_zv);
			INIT_PZVAL_COPY(new_zv, *arr);
			*arr = new_zv;
			zval_copy_ctor(new_zv);
		}
	}

	if ((flags & PH_COPY) == PH_COPY) {
		Z_ADDREF_PP(value);
	}

	return zend_hash_quick_update(Z_ARRVAL_PP(arr), index, index_length, key, value, sizeof(zval *), NULL);
}
Пример #2
0
/**
 * @brief Updates value in @a arr at position @a index with @a value using the precomputed hash @a key
 * @param[in,out] arr Array
 * @param index Index
 * @param index_length Length of the index, should include the trailing zero
 * @param key Precomputed hash of @c value
 * @param value Value
 * @param flags Flags
 * @return Whether the operation succeeded
 * @retval @c FAILURE Failure, @a arr is not an array
 * @retval @c SUCCESS Success
 * @throw @c E_WARNING if @a arr is not an array
 *
 * Equivalent to <tt>$arr[$index] = $value</tt> in PHP.
 *
 * Flags may be a bitwise OR of the following values:
 * @arg @c PH_CTOR: create a copy of @a value and work with that copy; @c *value will be updated with the newly constructed value
 * @arg @c PH_SEPARATE: separate @a arr if its reference count is greater than 1; @c *arr will contain the separated version
 * @arg @c PH_COPY: increment the reference count on @c **value
 */
int zephir_array_update_quick_string(zval **arr, const char *index, uint index_length, unsigned long key, zval **value, int flags) {

    if (Z_TYPE_PP(arr) != IS_ARRAY) {
        zend_error(E_WARNING, "Cannot use a scalar value as an array (3)");
        return FAILURE;
    }

    if ((flags & PH_CTOR) == PH_CTOR) {
        zval *new_zv;
        Z_DELREF_PP(value);
        ALLOC_ZVAL(new_zv);
        INIT_PZVAL_COPY(new_zv, *value);
        *value = new_zv;
        zval_copy_ctor(new_zv);
    }

    if ((flags & PH_SEPARATE) == PH_SEPARATE) {
        SEPARATE_ZVAL_IF_NOT_REF(arr);
    }

    if ((flags & PH_COPY) == PH_COPY) {
        Z_ADDREF_PP(value);
    }

    return zend_hash_quick_update(Z_ARRVAL_PP(arr), index, index_length, key, value, sizeof(zval *), NULL);
}
Пример #3
0
static int32_t qb_transfer_value_to_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) {
	int32_t result = TRUE;
	if(ivar->flags & QB_VARIABLE_IMPORTED) {
		USE_TSRM
		zval *zvalue = ivar->value, **p_zvalue = ivar->value_pointer;
		if(!IS_READ_ONLY(ivar->address)) {
			if(zvalue) {
				// separate the zval first, since we're modifying it
				SEPARATE_ZVAL_IF_NOT_REF(&zvalue);
			} else {
				ALLOC_INIT_ZVAL(zvalue);
			}
			if(!qb_transfer_value_to_zval(scope->storage, ivar->address, zvalue)) {
				uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
				qb_append_exception_variable_name(ivar TSRMLS_CC);
				qb_set_exception_line_id(line_id TSRMLS_CC);
				result = FALSE;
			}

			if(p_zvalue) {
				*p_zvalue = zvalue;
			} else {
				if(ivar->flags & QB_VARIABLE_GLOBAL) {
					zend_hash_quick_update(&EG(symbol_table), ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &zvalue, sizeof(zval *), NULL);
				} else if(ivar->flags & QB_VARIABLE_CLASS_INSTANCE) {
					zval *container = scope->object;
					zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC);
					Z_OBJ_WRITE_PROP(container, name, zvalue);
				}
			}
		}
		if(!p_zvalue && zvalue) {
			// if p_zvalue isn't null, then something else has put a refcount 
			// on the zval (and we didn't increment it earlier)
			zval_ptr_dtor(&zvalue);
		}
		ivar->value_pointer = NULL;
		ivar->value = NULL;
		ivar->flags &= ~QB_VARIABLE_IMPORTED;
	}
	return result;
}
Пример #4
0
static int32_t qb_transfer_value_to_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) {
	int32_t result = TRUE;
	if(ivar->flags & QB_VARIABLE_IMPORTED) {
		USE_TSRM
		if(!READ_ONLY(ivar->address)) {
			zval *zvalue;
			if(ivar->value_pointer) {
				zvalue = *ivar->value_pointer;
			} else {
				zvalue = ivar->value;
				// separate the zval first, since we're modifying it
				SEPARATE_ZVAL_TO_MAKE_IS_REF(&zvalue);
			}
			if(!zvalue) {
				ALLOC_INIT_ZVAL(zvalue);
				if(ivar->value_pointer) {
					*ivar->value_pointer = zvalue;
				}
			}
			if(!qb_transfer_value_to_zval(scope->storage, ivar->address, zvalue)) {
				uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
				qb_set_exception_line_id(line_id TSRMLS_CC);
				result = FALSE;
			}

			if(!ivar->value_pointer) {
				if(ivar->flags & QB_VARIABLE_GLOBAL) {
					zend_hash_quick_update(&EG(symbol_table), ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &zvalue, sizeof(zval *), NULL);
				} else if(ivar->flags & QB_VARIABLE_CLASS_INSTANCE) {
					zval *container = scope->zend_object;
					zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC);
					Z_OBJ_WRITE_PROP(container, name, zvalue);
					zval_ptr_dtor(&zvalue);
				}
			}
			ivar->value_pointer = NULL;
			ivar->value = NULL;
		}
		ivar->flags &= ~QB_VARIABLE_IMPORTED;
	}