~ubuntu-branches/ubuntu/oneiric/ghostscript/oneiric

« back to all changes in this revision

Viewing changes to psi/zgeneric.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2011-07-15 16:49:55 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20110715164955-uga6qibao6kez05c
Tags: 9.04~dfsg~20110715-0ubuntu1
* New upstream release
   - GIT snapshot from Jult, 12 2011.
* debian/patches/020110406~a54df2d.patch,
  debian/patches/020110408~0791cc8.patch,
  debian/patches/020110408~507cbee.patch,
  debian/patches/020110411~4509a49.patch,
  debian/patches/020110412~78bb9a6.patch,
  debian/patches/020110418~a05ab8a.patch,
  debian/patches/020110420~20b6c78.patch,
  debian/patches/020110420~4ddefa2.patch: Removed upstream patches.
* debian/rules: Generate ABI version number (variable "abi") correctly,
  cutting off repackaging and pre-release parts.
* debian/rules: Added ./lcms2/ directory to DEB_UPSTREAM_REPACKAGE_EXCLUDES.
* debian/copyright: Added lcms2/* to the list of excluded files.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
2
   All Rights Reserved.
3
 
  
 
3
 
4
4
   This software is provided AS-IS with no warranty, either express or
5
5
   implied.
6
6
 
11
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
12
*/
13
13
 
14
 
/* $Id: zgeneric.c 9778 2009-06-05 05:55:54Z alexcher $ */
 
14
/* $Id$ */
15
15
/* Array/string/dictionary generic operators for PostScript */
16
16
#include "memory_.h"
17
17
#include "ghost.h"
49
49
    int type = r_type(op);
50
50
 
51
51
    if (type == t_integer)
52
 
        return zcopy_integer(i_ctx_p);
 
52
        return zcopy_integer(i_ctx_p);
53
53
    check_op(2);
54
54
    switch (type) {
55
 
        case t_array:
56
 
        case t_string:
57
 
            return zcopy_interval(i_ctx_p);
58
 
        case t_dictionary:
59
 
            return zcopy_dict(i_ctx_p);
60
 
        default:
61
 
            return_op_typecheck(op);
 
55
        case t_array:
 
56
        case t_string:
 
57
            return zcopy_interval(i_ctx_p);
 
58
        case t_dictionary:
 
59
            return zcopy_dict(i_ctx_p);
 
60
        default:
 
61
            return_op_typecheck(op);
62
62
    }
63
63
}
64
64
 
72
72
    int code;
73
73
 
74
74
    if ((uint) op->value.intval > (uint)(op - osbot)) {
75
 
        /* There might be enough elements in other blocks. */
76
 
        check_type(*op, t_integer);
77
 
        if (op->value.intval >= (int)ref_stack_count(&o_stack)) 
 
75
        /* There might be enough elements in other blocks. */
 
76
        check_type(*op, t_integer);
 
77
        if (op->value.intval >= (int)ref_stack_count(&o_stack))
78
78
            return_error(e_stackunderflow);
79
 
        if (op->value.intval < 0) 
 
79
        if (op->value.intval < 0)
80
80
            return_error(e_rangecheck);
81
81
        check_int_ltu(*op, ref_stack_count(&o_stack));
82
 
        count = op->value.intval;
 
82
        count = op->value.intval;
83
83
    } else if (op1 + (count = op->value.intval) <= ostop) {
84
 
        /* Fast case. */
85
 
        memcpy((char *)op, (char *)(op - count), count * sizeof(ref));
86
 
        push(count - 1);
87
 
        return 0;
 
84
        /* Fast case. */
 
85
        memcpy((char *)op, (char *)(op - count), count * sizeof(ref));
 
86
        push(count - 1);
 
87
        return 0;
88
88
    }
89
89
    /* Do it the slow, general way. */
90
90
    code = ref_stack_push(&o_stack, count - 1);
91
91
    if (code < 0)
92
 
        return code;
 
92
        return code;
93
93
    for (i = 0; i < count; i++)
94
 
        *ref_stack_index(&o_stack, i) =
95
 
            *ref_stack_index(&o_stack, i + count);
 
94
        *ref_stack_index(&o_stack, i) =
 
95
            *ref_stack_index(&o_stack, i + count);
96
96
    return 0;
97
97
}
98
98
 
106
106
    int code = copy_interval(i_ctx_p, op, 0, op1, "copy");
107
107
 
108
108
    if (code < 0)
109
 
        return code;
 
109
        return code;
110
110
    r_set_size(op, r_size(op1));
111
111
    *op1 = *op;
112
112
    pop(1);
119
119
{
120
120
    os_ptr op = osp;
121
121
    switch (r_type(op)) {
122
 
        case t_array:
123
 
        case t_string:
124
 
        case t_mixedarray:
125
 
        case t_shortarray:
126
 
            check_read(*op);
127
 
            make_int(op, r_size(op));
128
 
            return 0;
129
 
        case t_dictionary:
130
 
            check_dict_read(*op);
131
 
            make_int(op, dict_length(op));
132
 
            return 0;
133
 
        case t_name: {
134
 
            ref str;
 
122
        case t_array:
 
123
        case t_string:
 
124
        case t_mixedarray:
 
125
        case t_shortarray:
 
126
            check_read(*op);
 
127
            make_int(op, r_size(op));
 
128
            return 0;
 
129
        case t_dictionary:
 
130
            check_dict_read(*op);
 
131
            make_int(op, dict_length(op));
 
132
            return 0;
 
133
        case t_name: {
 
134
            ref str;
135
135
 
136
 
            name_string_ref(imemory, op, &str);
137
 
            make_int(op, r_size(&str));
138
 
            return 0;
139
 
        }
140
 
        case t_astruct:
141
 
            if (gs_object_type(imemory, op->value.pstruct) != &st_bytes)
142
 
                return_error(e_typecheck);
143
 
            check_read(*op);
144
 
            make_int(op, gs_object_size(imemory, op->value.pstruct));
145
 
            return 0;
146
 
        default:
147
 
            return_op_typecheck(op);
 
136
            name_string_ref(imemory, op, &str);
 
137
            make_int(op, r_size(&str));
 
138
            return 0;
 
139
        }
 
140
        case t_astruct:
 
141
            if (gs_object_type(imemory, op->value.pstruct) != &st_bytes)
 
142
                return_error(e_typecheck);
 
143
            check_read(*op);
 
144
            make_int(op, gs_object_size(imemory, op->value.pstruct));
 
145
            return 0;
 
146
        default:
 
147
            return_op_typecheck(op);
148
148
    }
149
149
}
150
150
 
159
159
    ref *pvalue;
160
160
 
161
161
    switch (r_type(op1)) {
162
 
        case t_dictionary:
163
 
            check_dict_read(*op1);
164
 
            if (dict_find(op1, op, &pvalue) <= 0)
165
 
                return_error(e_undefined);
166
 
            op[-1] = *pvalue;
167
 
            break;
168
 
        case t_string:
169
 
            check_read(*op1);
170
 
            check_int_ltu(*op, r_size(op1));
171
 
            make_int(op1, op1->value.bytes[(uint) op->value.intval]);
172
 
            break;
173
 
        case t_array:
174
 
        case t_mixedarray:
175
 
        case t_shortarray:
176
 
            check_type(*op, t_integer);
177
 
            check_read(*op1);
178
 
            code = array_get(imemory, op1, op->value.intval, op1);
179
 
            if (code < 0) 
180
 
                return code;
181
 
            break;
 
162
        case t_dictionary:
 
163
            check_dict_read(*op1);
 
164
            if (dict_find(op1, op, &pvalue) <= 0)
 
165
                return_error(e_undefined);
 
166
            op[-1] = *pvalue;
 
167
            break;
 
168
        case t_string:
 
169
            check_read(*op1);
 
170
            check_int_ltu(*op, r_size(op1));
 
171
            make_int(op1, op1->value.bytes[(uint) op->value.intval]);
 
172
            break;
 
173
        case t_array:
 
174
        case t_mixedarray:
 
175
        case t_shortarray:
 
176
            check_type(*op, t_integer);
 
177
            check_read(*op1);
 
178
            code = array_get(imemory, op1, op->value.intval, op1);
 
179
            if (code < 0)
 
180
                return code;
 
181
            break;
182
182
        case t__invalid:
183
183
            return_error(e_stackunderflow);
184
184
        default:
185
 
            return_error(e_typecheck); 
 
185
            return_error(e_typecheck);
186
186
    }
187
187
    pop(1);
188
188
    return 0;
201
201
    uint ssize;
202
202
 
203
203
    switch (r_type(op2)) {
204
 
        case t_dictionary:
205
 
            if (i_ctx_p->in_superexec == 0)
206
 
                check_dict_write(*op2);
207
 
            {
208
 
                int code = idict_put(op2, op1, op);
209
 
 
210
 
                if (code < 0)
211
 
                    return code;        /* error */
212
 
            }
213
 
            break;
214
 
        case t_array:
215
 
            check_write(*op2);
216
 
            check_int_ltu(*op1, r_size(op2));
217
 
            store_check_dest(op2, op);
218
 
            {
219
 
                ref *eltp = op2->value.refs + (uint) op1->value.intval;
220
 
 
221
 
                ref_assign_old(op2, eltp, op, "put");
222
 
            }
223
 
            break;
224
 
        case t_mixedarray:      /* packed arrays are read-only */
225
 
        case t_shortarray:
226
 
            return_error(e_invalidaccess);
227
 
        case t_string:
228
 
            sdata = op2->value.bytes;
229
 
            ssize = r_size(op2);
 
204
        case t_dictionary:
 
205
            if (i_ctx_p->in_superexec == 0)
 
206
                check_dict_write(*op2);
 
207
            {
 
208
                int code = idict_put(op2, op1, op);
 
209
 
 
210
                if (code < 0)
 
211
                    return code;        /* error */
 
212
            }
 
213
            break;
 
214
        case t_array:
 
215
            check_write(*op2);
 
216
            check_int_ltu(*op1, r_size(op2));
 
217
            store_check_dest(op2, op);
 
218
            {
 
219
                ref *eltp = op2->value.refs + (uint) op1->value.intval;
 
220
 
 
221
                ref_assign_old(op2, eltp, op, "put");
 
222
            }
 
223
            break;
 
224
        case t_mixedarray:      /* packed arrays are read-only */
 
225
        case t_shortarray:
 
226
            return_error(e_invalidaccess);
 
227
        case t_string:
 
228
            sdata = op2->value.bytes;
 
229
            ssize = r_size(op2);
230
230
str:        check_write(*op2);
231
 
            check_int_ltu(*op1, ssize);
232
 
            check_int_leu(*op, 0xff);
233
 
            sdata[(uint)op1->value.intval] = (byte)op->value.intval;
234
 
            break;
235
 
        case t_astruct:
236
 
            if (gs_object_type(imemory, op2->value.pstruct) != &st_bytes)
237
 
                return_error(e_typecheck);
238
 
            sdata = r_ptr(op2, byte);
239
 
            ssize = gs_object_size(imemory, op2->value.pstruct);
240
 
            goto str;
241
 
        default:
242
 
            return_op_typecheck(op2);
 
231
            check_int_ltu(*op1, ssize);
 
232
            check_int_leu(*op, 0xff);
 
233
            sdata[(uint)op1->value.intval] = (byte)op->value.intval;
 
234
            break;
 
235
        case t_astruct:
 
236
            if (gs_object_type(imemory, op2->value.pstruct) != &st_bytes)
 
237
                return_error(e_typecheck);
 
238
            sdata = r_ptr(op2, byte);
 
239
            ssize = gs_object_size(imemory, op2->value.pstruct);
 
240
            goto str;
 
241
        default:
 
242
            return_op_typecheck(op2);
243
243
    }
244
244
    pop(3);
245
245
    return 0;
265
265
 
266
266
    switch (r_type(op2)) {
267
267
    case t_array:
268
 
        check_int_ltu(*op1, r_size(op2));
269
 
        if (r_space(op2) > r_space(op)) {
270
 
            if (imemory_save_level(iimemory))
271
 
                return_error(e_invalidaccess);
272
 
        }
273
 
        {
274
 
            ref *eltp = op2->value.refs + (uint) op1->value.intval;
 
268
        check_int_ltu(*op1, r_size(op2));
 
269
        if (r_space(op2) > r_space(op)) {
 
270
            if (imemory_save_level(iimemory))
 
271
                return_error(e_invalidaccess);
 
272
        }
 
273
        {
 
274
            ref *eltp = op2->value.refs + (uint) op1->value.intval;
275
275
 
276
 
            ref_assign_old(op2, eltp, op, "put");
277
 
        }
278
 
        break;
 
276
            ref_assign_old(op2, eltp, op, "put");
 
277
        }
 
278
        break;
279
279
    case t_dictionary:
280
 
        if (op2->value.pdict == systemdict->value.pdict ||
281
 
            !imemory_save_level(iimemory)
282
 
            ) {
283
 
            uint space = r_space(op2);
 
280
        if (op2->value.pdict == systemdict->value.pdict ||
 
281
            !imemory_save_level(iimemory)
 
282
            ) {
 
283
            uint space = r_space(op2);
284
284
 
285
 
            r_set_space(op2, avm_local);
286
 
            code = idict_put(op2, op1, op);
287
 
            r_set_space(op2, space);
288
 
        } else
289
 
            code = idict_put(op2, op1, op);
290
 
        if (code < 0)
291
 
            return code;
292
 
        break;
 
285
            r_set_space(op2, avm_local);
 
286
            code = idict_put(op2, op1, op);
 
287
            r_set_space(op2, space);
 
288
        } else
 
289
            code = idict_put(op2, op1, op);
 
290
        if (code < 0)
 
291
            return code;
 
292
        break;
293
293
    default:
294
 
        return_error(e_typecheck);
 
294
        return_error(e_typecheck);
295
295
    }
296
296
    pop(3);
297
297
    return 0;
308
308
    uint count;
309
309
 
310
310
    switch (r_type(op2)) {
311
 
        default:
312
 
            return_op_typecheck(op2);
313
 
        case t_array:
314
 
        case t_string:
315
 
        case t_mixedarray:
316
 
        case t_shortarray:;
 
311
        default:
 
312
            return_op_typecheck(op2);
 
313
        case t_array:
 
314
        case t_string:
 
315
        case t_mixedarray:
 
316
        case t_shortarray:;
317
317
    }
318
318
    check_read(*op2);
319
319
    check_int_leu(*op1, r_size(op2));
321
321
    check_int_leu(*op, r_size(op2) - index);
322
322
    count = op->value.intval;
323
323
    switch (r_type(op2)) {
324
 
        case t_array:
325
 
            op2->value.refs += index;
326
 
            break;
327
 
        case t_string:
328
 
            op2->value.bytes += index;
329
 
            break;
330
 
        case t_mixedarray: {
331
 
            const ref_packed *packed = op2->value.packed;
 
324
        case t_array:
 
325
            op2->value.refs += index;
 
326
            break;
 
327
        case t_string:
 
328
            op2->value.bytes += index;
 
329
            break;
 
330
        case t_mixedarray: {
 
331
            const ref_packed *packed = op2->value.packed;
332
332
 
333
 
            for (; index--;)
334
 
                packed = packed_next(packed);
335
 
            op2->value.packed = packed;
336
 
            break;
337
 
        }
338
 
        case t_shortarray:
339
 
            op2->value.packed += index;
340
 
            break;
 
333
            for (; index--;)
 
334
                packed = packed_next(packed);
 
335
            op2->value.packed = packed;
 
336
            break;
 
337
        }
 
338
        case t_shortarray:
 
339
            op2->value.packed += index;
 
340
            break;
341
341
    }
342
342
    r_set_size(op2, count);
343
343
    pop(2);
356
356
    int code;
357
357
 
358
358
    switch (r_type(opto)) {
359
 
        default:
 
359
        default:
360
360
            return_error(e_typecheck);
361
361
        case t__invalid:
362
362
            if (r_type(op) != t_array && r_type(op) != t_string && r_type(op) != t__invalid)
363
363
                return_error(e_typecheck); /* to match Distiller */
364
364
            else
365
365
                return_error(e_stackunderflow);
366
 
        case t_mixedarray:
367
 
        case t_shortarray:
368
 
            return_error(e_invalidaccess);
369
 
        case t_array:
370
 
        case t_string:
371
 
            check_write(*opto);
372
 
            check_int_leu(*opindex, r_size(opto));
373
 
            code = copy_interval(i_ctx_p, opto, (uint)(opindex->value.intval),
374
 
                                 op, "putinterval");
375
 
            break;
376
 
        case t_astruct: {
377
 
            uint dsize, ssize, index;
 
366
        case t_mixedarray:
 
367
        case t_shortarray:
 
368
            return_error(e_invalidaccess);
 
369
        case t_array:
 
370
        case t_string:
 
371
            check_write(*opto);
 
372
            check_int_leu(*opindex, r_size(opto));
 
373
            code = copy_interval(i_ctx_p, opto, (uint)(opindex->value.intval),
 
374
                                 op, "putinterval");
 
375
            break;
 
376
        case t_astruct: {
 
377
            uint dsize, ssize, index;
378
378
 
379
 
            check_write(*opto);
380
 
            if (gs_object_type(imemory, opto->value.pstruct) != &st_bytes)
381
 
                return_error(e_typecheck);
382
 
            dsize = gs_object_size(imemory, opto->value.pstruct);
383
 
            check_int_leu(*opindex, dsize);
384
 
            index = (uint)opindex->value.intval;
385
 
            check_read_type(*op, t_string);
386
 
            ssize = r_size(op);
387
 
            if (ssize > dsize - index)
388
 
                return_error(e_rangecheck);
389
 
            memcpy(r_ptr(opto, byte) + index, op->value.const_bytes, ssize);
390
 
            code = 0;
391
 
            break;
392
 
        }
 
379
            check_write(*opto);
 
380
            if (gs_object_type(imemory, opto->value.pstruct) != &st_bytes)
 
381
                return_error(e_typecheck);
 
382
            dsize = gs_object_size(imemory, opto->value.pstruct);
 
383
            check_int_leu(*opindex, dsize);
 
384
            index = (uint)opindex->value.intval;
 
385
            check_read_type(*op, t_string);
 
386
            ssize = r_size(op);
 
387
            if (ssize > dsize - index)
 
388
                return_error(e_rangecheck);
 
389
            memcpy(r_ptr(opto, byte) + index, op->value.const_bytes, ssize);
 
390
            code = 0;
 
391
            break;
 
392
        }
393
393
    }
394
394
    if (code >= 0)
395
 
        pop(3);
 
395
        pop(3);
396
396
    return code;
397
397
}
398
398
 
415
415
    check_estack(6);
416
416
    check_proc(*op);
417
417
    switch (r_type(obj)) {
418
 
        default:
419
 
            return_op_typecheck(obj);
420
 
        case t_array:
421
 
            check_read(*obj);
422
 
            make_op_estack(cproc, array_continue);
423
 
            break;
424
 
        case t_dictionary:
425
 
            check_dict_read(*obj);
426
 
            make_int(cproc, dict_first(obj));
427
 
            ++cproc;
428
 
            make_op_estack(cproc, dict_continue);
429
 
            break;
430
 
        case t_string:
431
 
            check_read(*obj);
432
 
            make_op_estack(cproc, string_continue);
433
 
            break;
434
 
        case t_mixedarray:
435
 
        case t_shortarray:
436
 
            check_read(*obj);
437
 
            make_op_estack(cproc, packedarray_continue);
438
 
            break;
 
418
        default:
 
419
            return_op_typecheck(obj);
 
420
        case t_array:
 
421
            check_read(*obj);
 
422
            make_op_estack(cproc, array_continue);
 
423
            break;
 
424
        case t_dictionary:
 
425
            check_dict_read(*obj);
 
426
            make_int(cproc, dict_first(obj));
 
427
            ++cproc;
 
428
            make_op_estack(cproc, dict_continue);
 
429
            break;
 
430
        case t_string:
 
431
            check_read(*obj);
 
432
            make_op_estack(cproc, string_continue);
 
433
            break;
 
434
        case t_mixedarray:
 
435
        case t_shortarray:
 
436
            check_read(*obj);
 
437
            make_op_estack(cproc, packedarray_continue);
 
438
            break;
439
439
    }
440
440
    /*
441
441
     * Push:
460
460
    es_ptr obj = esp - 1;
461
461
 
462
462
    if (r_size(obj)) {          /* continue */
463
 
        push(1);
464
 
        r_dec_size(obj, 1);
465
 
        *op = *obj->value.refs;
466
 
        obj->value.refs++;
467
 
        esp += 2;
468
 
        *esp = obj[1];
469
 
        return o_push_estack;
 
463
        push(1);
 
464
        r_dec_size(obj, 1);
 
465
        *op = *obj->value.refs;
 
466
        obj->value.refs++;
 
467
        esp += 2;
 
468
        *esp = obj[1];
 
469
        return o_push_estack;
470
470
    } else {                    /* done */
471
 
        esp -= 3;               /* pop mark, object, proc */
472
 
        return o_pop_estack;
 
471
        esp -= 3;               /* pop mark, object, proc */
 
472
        return o_pop_estack;
473
473
    }
474
474
}
475
475
/* Continuation operator for dictionaries */
482
482
 
483
483
    push(2);                    /* make room for key and value */
484
484
    if ((index = dict_next(obj, index, op - 1)) >= 0) { /* continue */
485
 
        esp->value.intval = index;
486
 
        esp += 2;
487
 
        *esp = obj[1];
488
 
        return o_push_estack;
 
485
        esp->value.intval = index;
 
486
        esp += 2;
 
487
        *esp = obj[1];
 
488
        return o_push_estack;
489
489
    } else {                    /* done */
490
 
        pop(2);                 /* undo push */
491
 
        esp -= 4;               /* pop mark, object, proc, index */
492
 
        return o_pop_estack;
 
490
        pop(2);                 /* undo push */
 
491
        esp -= 4;               /* pop mark, object, proc, index */
 
492
        return o_pop_estack;
493
493
    }
494
494
}
495
495
/* Continuation operator for strings */
500
500
    es_ptr obj = esp - 1;
501
501
 
502
502
    if (r_size(obj)) {          /* continue */
503
 
        r_dec_size(obj, 1);
504
 
        push(1);
505
 
        make_int(op, *obj->value.bytes);
506
 
        obj->value.bytes++;
507
 
        esp += 2;
508
 
        *esp = obj[1];
509
 
        return o_push_estack;
 
503
        r_dec_size(obj, 1);
 
504
        push(1);
 
505
        make_int(op, *obj->value.bytes);
 
506
        obj->value.bytes++;
 
507
        esp += 2;
 
508
        *esp = obj[1];
 
509
        return o_push_estack;
510
510
    } else {                    /* done */
511
 
        esp -= 3;               /* pop mark, object, proc */
512
 
        return o_pop_estack;
 
511
        esp -= 3;               /* pop mark, object, proc */
 
512
        return o_pop_estack;
513
513
    }
514
514
}
515
515
/* Continuation operator for packed arrays */
520
520
    es_ptr obj = esp - 1;
521
521
 
522
522
    if (r_size(obj)) {          /* continue */
523
 
        const ref_packed *packed = obj->value.packed;
 
523
        const ref_packed *packed = obj->value.packed;
524
524
 
525
 
        r_dec_size(obj, 1);
526
 
        push(1);
527
 
        packed_get(imemory, packed, op);
528
 
        obj->value.packed = packed_next(packed);
529
 
        esp += 2;
530
 
        *esp = obj[1];
531
 
        return o_push_estack;
 
525
        r_dec_size(obj, 1);
 
526
        push(1);
 
527
        packed_get(imemory, packed, op);
 
528
        obj->value.packed = packed_next(packed);
 
529
        esp += 2;
 
530
        *esp = obj[1];
 
531
        return o_push_estack;
532
532
    } else {                    /* done */
533
 
        esp -= 3;               /* pop mark, object, proc */
534
 
        return o_pop_estack;
 
533
        esp -= 3;               /* pop mark, object, proc */
 
534
        return o_pop_estack;
535
535
    }
536
536
}
537
537
/* Vacuous cleanup procedure */
553
553
    {"1length", zlength},
554
554
    {"3put", zput},
555
555
    {"3putinterval", zputinterval},
556
 
                /* Internal operators */
 
556
                /* Internal operators */
557
557
    {"0%array_continue", array_continue},
558
558
    {"0%dict_continue", dict_continue},
559
559
    {"0%packedarray_continue", packedarray_continue},
570
570
/* its length; nothing else has been checked. */
571
571
static int
572
572
copy_interval(i_ctx_t *i_ctx_p /* for ref_assign_old */, os_ptr prto,
573
 
              uint index, os_ptr prfrom, client_name_t cname)
 
573
              uint index, os_ptr prfrom, client_name_t cname)
574
574
{
575
575
    int fromtype = r_type(prfrom);
576
576
    uint fromsize = r_size(prfrom);
577
577
 
578
578
    if (!(fromtype == r_type(prto) ||
579
 
          ((fromtype == t_shortarray || fromtype == t_mixedarray) &&
580
 
           r_type(prto) == t_array))
581
 
        )
582
 
        return_op_typecheck(prfrom);
 
579
          ((fromtype == t_shortarray || fromtype == t_mixedarray) &&
 
580
           r_type(prto) == t_array))
 
581
        )
 
582
        return_op_typecheck(prfrom);
583
583
    check_read(*prfrom);
584
584
    check_write(*prto);
585
585
    if (fromsize > r_size(prto) - index)
586
 
        return_error(e_rangecheck);
 
586
        return_error(e_rangecheck);
587
587
    switch (fromtype) {
588
 
        case t_array:
589
 
            {                   /* We have to worry about aliasing, */
590
 
                /* but refcpy_to_old takes care of it for us. */
591
 
                return refcpy_to_old(prto, index, prfrom->value.refs,
592
 
                                     fromsize, idmemory, cname);
593
 
            }
594
 
        case t_string:
595
 
            {   /* memmove takes care of aliasing. */
596
 
                memmove(prto->value.bytes + index, prfrom->value.bytes,
597
 
                        fromsize);
598
 
            }
599
 
            break;
600
 
        case t_mixedarray:
601
 
        case t_shortarray:
602
 
            {   /* We don't have to worry about aliasing, because */
603
 
                /* packed arrays are read-only and hence the destination */
604
 
                /* can't be a packed array. */
605
 
                uint i;
606
 
                const ref_packed *packed = prfrom->value.packed;
607
 
                ref *pdest = prto->value.refs + index;
608
 
                ref elt;
 
588
        case t_array:
 
589
            {                   /* We have to worry about aliasing, */
 
590
                /* but refcpy_to_old takes care of it for us. */
 
591
                return refcpy_to_old(prto, index, prfrom->value.refs,
 
592
                                     fromsize, idmemory, cname);
 
593
            }
 
594
        case t_string:
 
595
            {   /* memmove takes care of aliasing. */
 
596
                memmove(prto->value.bytes + index, prfrom->value.bytes,
 
597
                        fromsize);
 
598
            }
 
599
            break;
 
600
        case t_mixedarray:
 
601
        case t_shortarray:
 
602
            {   /* We don't have to worry about aliasing, because */
 
603
                /* packed arrays are read-only and hence the destination */
 
604
                /* can't be a packed array. */
 
605
                uint i;
 
606
                const ref_packed *packed = prfrom->value.packed;
 
607
                ref *pdest = prto->value.refs + index;
 
608
                ref elt;
609
609
 
610
 
                for (i = 0; i < fromsize; i++, pdest++) {
611
 
                    packed_get(imemory, packed, &elt);
612
 
                    ref_assign_old(prto, pdest, &elt, cname);
613
 
                    packed = packed_next(packed);
614
 
                }
615
 
            }
616
 
            break;
 
610
                for (i = 0; i < fromsize; i++, pdest++) {
 
611
                    packed_get(imemory, packed, &elt);
 
612
                    ref_assign_old(prto, pdest, &elt, cname);
 
613
                    packed = packed_next(packed);
 
614
                }
 
615
            }
 
616
            break;
617
617
    }
618
618
    return 0;
619
619
}