Exemplo n.º 1
0
/* its length; nothing else has been checked. */
static int
copy_interval(i_ctx_t *i_ctx_p /* for ref_assign_old */, os_ptr prto,
	      uint index, os_ptr prfrom, client_name_t cname)
{
    int fromtype = r_type(prfrom);
    uint fromsize = r_size(prfrom);

    if (!(fromtype == r_type(prto) ||
	  ((fromtype == t_shortarray || fromtype == t_mixedarray) &&
	   r_type(prto) == t_array))
	)
	return_op_typecheck(prfrom);
    check_read(*prfrom);
    check_write(*prto);
    if (fromsize > r_size(prto) - index)
	return_error(e_rangecheck);
    switch (fromtype) {
	case t_array:
	    {			/* We have to worry about aliasing, */
		/* but refcpy_to_old takes care of it for us. */
		return refcpy_to_old(prto, index, prfrom->value.refs,
				     fromsize, idmemory, cname);
	    }
	case t_string:
	    {	/* memmove takes care of aliasing. */
		memmove(prto->value.bytes + index, prfrom->value.bytes,
			fromsize);
	    }
	    break;
	case t_mixedarray:
	case t_shortarray:
	    {	/* We don't have to worry about aliasing, because */
		/* packed arrays are read-only and hence the destination */
		/* can't be a packed array. */
		uint i;
		const ref_packed *packed = prfrom->value.packed;
		ref *pdest = prto->value.refs + index;
		ref elt;

		for (i = 0; i < fromsize; i++, pdest++) {
		    packed_get(imemory, packed, &elt);
		    ref_assign_old(prto, pdest, &elt, cname);
		    packed = packed_next(packed);
		}
	    }
	    break;
    }
    return 0;
}
Exemplo n.º 2
0
/* <obj_0> ... <obj_n-1> <array> astore <array> */
static int
zastore(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint size;
    int code;

    if (!r_is_array(op))
        return_op_typecheck(op);
    size = r_size(op);
    /* Amazingly, the following is valid: 0 array noaccess astore */
    if (size == 0)
        return 0;
    if (!r_has_type_attrs(op, t_array, a_write))
        return_error(gs_error_invalidaccess);
    if (size > op - osbot) {
        /* The store operation might involve other stack segments. */
        ref arr;

        if (size >= ref_stack_count(&o_stack))
            return_error(gs_error_stackunderflow);
        arr = *op;
        code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
                               "astore");
        if (code < 0)
            return code;
        ref_stack_pop(&o_stack, size);
        *ref_stack_index(&o_stack, 0) = arr;
    } else {
        code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
        if (code < 0)
            return code;
        op[-(int)size] = *op;
        pop(size);
    }
    return 0;
}