Exemplo n.º 1
0
/* {{{ my_copy_zval */
zval* my_copy_zval(zval* dst, const zval* src, int persistent TSRMLS_DC)
{
    zval **tmp;
    assert(dst != NULL);
    assert(src != NULL);
    memcpy(dst, src, sizeof(zval));

    /* deep copies are refcount(1), but moved up for recursive 
     * arrays,  which end up being add_ref'd during its copy. */
    Z_SET_REFCOUNT_P(dst, 1);
    Z_UNSET_ISREF_P(dst);

    switch (src->type & IS_CONSTANT_TYPE_MASK) {
    case IS_RESOURCE:
        php_error(E_ERROR, "Cannot copy resource");
        break;
    case IS_BOOL:
    case IS_LONG:
    case IS_DOUBLE:
    case IS_NULL:
        break;

    case IS_CONSTANT:
    case IS_STRING:
        if (src->value.str.val) {
            dst->value.str.val = pestrndup(src->value.str.val, src->value.str.len, persistent);
        }
        break;

#if ZEND_EXTENSION_API_NO < PHP_5_5_X_API_NO
    case IS_CONSTANT_ARRAY:
#endif
    case IS_ARRAY:
        dst->value.ht = my_copy_hashtable(NULL, src->value.ht, (ht_copy_fun_t) my_copy_zval_ptr, (void*) &tmp, sizeof(zval *), persistent TSRMLS_CC);
        break;

    // XXX: we don't serialize object.
    case IS_OBJECT:
        php_error(E_ERROR, "Cannot copy Object.");
        break;
#ifdef ZEND_ENGINE_2_4
    case IS_CALLABLE:
        php_error(E_ERROR, "Cannot copy Callable.");
        // XXX: we don't serialize callbable object.
        break;
#endif
    default:
        assert(0);
    }
    return dst;
}
Exemplo n.º 2
0
/* {{{ my_copy_zval */
static APC_HOTSPOT void my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt)
{
    apc_pool* pool = ctxt->pool;

    assert(dst != NULL);
    assert(src != NULL);

	memcpy(dst, src, sizeof(zval));
	
	if (Z_REFCOUNTED_P(src)) {
		if (zend_hash_num_elements(&ctxt->copied)) {
            zval *rc = zend_hash_index_find(
                    &ctxt->copied, (uintptr_t) Z_COUNTED_P(src));
            if (rc) {
				ZVAL_COPY(dst, rc);
				return;
            }
		}
	}

    switch (Z_TYPE_P(src)) {
    case IS_RESOURCE:
    case IS_TRUE:
    case IS_FALSE:
    case IS_LONG:
    case IS_DOUBLE:
    case IS_NULL:
        break;

	case IS_REFERENCE:
		Z_REF_P(dst) = my_copy_reference(Z_REF_P(src), ctxt);
	break;

	case IS_INDIRECT:
		my_copy_zval(dst, Z_INDIRECT_P(src), ctxt);
	break;

    case IS_CONSTANT:
    case IS_STRING:	
		if (ctxt->copy == APC_COPY_OUT) {
			ZVAL_DUP(dst, src);
		} else {
			Z_TYPE_INFO_P(dst) = IS_STRING_EX;
			Z_STR_P(dst) = apc_pstrcpy(Z_STR_P(src), pool);
		}
        break;

    case IS_ARRAY:
        if(ctxt->serializer == NULL) {
			Z_ARRVAL_P(dst) = my_copy_hashtable(Z_ARRVAL_P(src), ctxt);
            break;
        }

		/* break intentionally omitted */

    case IS_OBJECT:
        if(ctxt->copy == APC_COPY_IN) {
            dst = my_serialize_object(dst, src, ctxt);
        } else dst = my_unserialize_object(dst, src, ctxt);
        break;

    case IS_CALLABLE:
        /* XXX implement this */
        assert(0);
        break;

    default:
        assert(0);
    }

	if (Z_REFCOUNTED_P(dst) && ctxt->copied.nTableSize) {
		zend_hash_index_update(&ctxt->copied, (uintptr_t) Z_COUNTED_P(src), dst);
	}
}