34
34
check_type(*op, t_integer);
35
35
if (op->value.intval < 0)
36
return_error(e_rangecheck);
36
return_error(e_rangecheck);
37
37
if (op->value.intval > max_array_size)
38
return_error(e_limitcheck);
38
return_error(e_limitcheck);
39
39
size = op->value.intval;
40
40
code = ialloc_ref_array((ref *)op, a_all, size, "array");
43
43
refset_null(op->value.refs, size);
55
55
ref_assign(&aref, op);
56
56
if (!r_is_array(&aref))
57
return_op_typecheck(op);
57
return_op_typecheck(op);
59
59
asize = r_size(&aref);
60
60
if (asize > ostop - op) { /* Use the slow, general algorithm. */
61
int code = ref_stack_push(&o_stack, asize);
63
const ref_packed *packed = aref.value.packed;
61
int code = ref_stack_push(&o_stack, asize);
63
const ref_packed *packed = aref.value.packed;
67
for (i = asize; i > 0; i--, packed = packed_next(packed))
68
packed_get(imemory, packed, ref_stack_index(&o_stack, i));
67
for (i = asize; i > 0; i--, packed = packed_next(packed))
68
packed_get(imemory, packed, ref_stack_index(&o_stack, i));
72
72
if (r_has_type(&aref, t_array))
73
memcpy(op, aref.value.refs, asize * sizeof(ref));
73
memcpy(op, aref.value.refs, asize * sizeof(ref));
76
const ref_packed *packed = aref.value.packed;
76
const ref_packed *packed = aref.value.packed;
79
for (i = 0; i < asize; i++, pdest++, packed = packed_next(packed))
80
packed_get(imemory, packed, pdest);
79
for (i = 0; i < asize; i++, pdest++, packed = packed_next(packed))
80
packed_get(imemory, packed, pdest);
83
83
ref_assign(op, &aref);
95
95
if (!r_is_array(op))
96
return_op_typecheck(op);
96
return_op_typecheck(op);
98
98
/* Amazingly, the following is valid: 0 array noaccess astore */
101
if (!r_has_type_attrs(op, t_array, a_write))
101
if (!r_has_type_attrs(op, t_array, a_write))
102
102
return_error(e_invalidaccess);
103
103
if (size > op - osbot) {
104
/* The store operation might involve other stack segments. */
104
/* The store operation might involve other stack segments. */
107
if (size >= ref_stack_count(&o_stack))
108
return_error(e_stackunderflow);
110
code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
114
ref_stack_pop(&o_stack, size);
115
*ref_stack_index(&o_stack, 0) = arr;
107
if (size >= ref_stack_count(&o_stack))
108
return_error(e_stackunderflow);
110
code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
114
ref_stack_pop(&o_stack, size);
115
*ref_stack_index(&o_stack, 0) = arr;
117
code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
120
op[-(int)size] = *op;
117
code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
120
op[-(int)size] = *op;