190
190
s_begin_inline(s, p, rlimit);
192
uint rcnt = rlimit - p;
193
uint top_size = p[1];
197
/* Extended header (2-byte array size, 4-byte length) */
201
s_end_inline(s, p - 1, rlimit);
202
pstate->s_scan_type = scanning_none;
205
pbs->top_size = top_size = sdecodeushort(p + 2, num_format);
206
pbs->lsize = lsize = sdecodeint32(p + 4, num_format);
207
if ((size = lsize) != lsize) {
208
scan_bos_error(pstate, "bin obj seq length too large");
209
return_error(e_limitcheck);
213
/* Normal header (1-byte array size, 2-byte length). */
214
/* We already checked rcnt >= 3. */
215
pbs->top_size = top_size;
216
pbs->lsize = size = sdecodeushort(p + 2, num_format);
219
if (size < hsize || (size - hsize) >> 3 < top_size) {
220
scan_bos_error(pstate, "sequence too short");
221
return_error(e_syntaxerror); /* size too small */
192
uint rcnt = rlimit - p;
193
uint top_size = p[1];
197
/* Extended header (2-byte array size, 4-byte length) */
201
s_end_inline(s, p - 1, rlimit);
202
pstate->s_scan_type = scanning_none;
205
pbs->top_size = top_size = sdecodeushort(p + 2, num_format);
206
pbs->lsize = lsize = sdecodeint32(p + 4, num_format);
207
if ((size = lsize) != lsize) {
208
scan_bos_error(pstate, "bin obj seq length too large");
209
return_error(e_limitcheck);
213
/* Normal header (1-byte array size, 2-byte length). */
214
/* We already checked rcnt >= 3. */
215
pbs->top_size = top_size;
216
pbs->lsize = size = sdecodeushort(p + 2, num_format);
219
if (size < hsize || (size - hsize) >> 3 < top_size) {
220
scan_bos_error(pstate, "sequence too short");
221
return_error(e_syntaxerror); /* size too small */
223
223
{ /* Preliminary syntax check to avoid potentialy large
224
224
* memory allocation on junk data. Bug 688833
226
226
const unsigned char *q, *rend = p + hsize + top_size*8;
228
228
if (rend > rlimit)
230
230
for (q = p + hsize + 1; q < rend; q += 8) {
231
231
int c = q[-1] & 0x7f;
232
232
if (c > 10 && c != BS_TYPE_DICTIONARY) {
233
scan_bos_error(pstate, "invalid object type");
234
return_error(e_syntaxerror);
233
scan_bos_error(pstate, "invalid object type");
234
return_error(e_syntaxerror);
237
scan_bos_error(pstate, "non-zero unused field");
238
return_error(e_syntaxerror);
237
scan_bos_error(pstate, "non-zero unused field");
238
return_error(e_syntaxerror);
243
* Preallocate an array large enough for the worst case,
244
* namely, all objects and no strings. Note that we must
245
* divide size by 8, not sizeof(ref), since array elements
246
* in binary tokens always occupy 8 bytes regardless of the
249
code = ialloc_ref_array(&pbs->bin_array,
250
a_all + a_executable, size / 8,
251
"binary object sequence(objects)");
256
s_end_inline(s, p, rlimit);
257
pbs->max_array_index = pbs->top_size = top_size;
258
pbs->min_string_index = pbs->size = size;
260
pstate->s_da.is_dynamic = false;
261
pstate->s_da.base = pstate->s_da.next =
262
pstate->s_da.limit = pstate->s_da.buf;
263
code = scan_bos_continue(i_ctx_p, pref, pstate);
264
if (code == scan_Refill || code < 0) {
265
/* Clean up array for GC. */
266
uint index = pbs->index;
243
* Preallocate an array large enough for the worst case,
244
* namely, all objects and no strings. Note that we must
245
* divide size by 8, not sizeof(ref), since array elements
246
* in binary tokens always occupy 8 bytes regardless of the
249
code = ialloc_ref_array(&pbs->bin_array,
250
a_all + a_executable, size / 8,
251
"binary object sequence(objects)");
256
s_end_inline(s, p, rlimit);
257
pbs->max_array_index = pbs->top_size = top_size;
258
pbs->min_string_index = pbs->size = size;
260
pstate->s_da.is_dynamic = false;
261
pstate->s_da.base = pstate->s_da.next =
262
pstate->s_da.limit = pstate->s_da.buf;
263
code = scan_bos_continue(i_ctx_p, pref, pstate);
264
if (code == scan_Refill || code < 0) {
265
/* Clean up array for GC. */
266
uint index = pbs->index;
268
refset_null(pbs->bin_array.value.refs + index,
269
r_size(&pbs->bin_array) - index);
268
refset_null(pbs->bin_array.value.refs + index,
269
r_size(&pbs->bin_array) - index);
296
296
s_begin_inline(s, p, rlimit);
297
297
wanted = bin_token_bytes[*p - MIN_BIN_TOKEN_TYPE] - 1;
300
make_int(pref, (p[1] ^ 128) - 128);
301
s_end_inline(s, p + 1, rlimit);
305
if (!num_is_valid(num_format))
306
return_error(e_syntaxerror);
307
wanted = 1 + encoded_number_bytes(num_format);
308
if (rlimit - p < wanted) {
309
s_end_inline(s, p - 1, rlimit);
310
pstate->s_scan_type = scanning_none;
313
code = sdecode_number(p + 2, num_format, pref);
319
case BT_FLOAT_IEEE_MSB:
320
case BT_FLOAT_IEEE_LSB:
321
case BT_FLOAT_NATIVE:
322
code = sdecode_number(p + 1, num_format, pref);
327
r_set_type(pref, code);
330
return_error(e_syntaxerror);
334
s_end_inline(s, p + wanted, rlimit);
339
return_error(e_syntaxerror);
340
make_bool(pref, arg);
341
s_end_inline(s, p + 1, rlimit);
346
case BT_STRING_64K_MSB:
347
case BT_STRING_64K_LSB:
348
arg = sdecodeushort(p + 1, num_format);
351
if (s->foreign && rlimit - p >= arg) {
353
* Reference the string directly in the buffer. It is
354
* marked writable for consistency with the non-direct
355
* case, but since the "buffer" may be data compiled into
356
* the executable, it is probably actually read-only.
358
s_end_inline(s, p, rlimit);
359
make_const_string(pref, a_all | avm_foreign, arg, sbufptr(s));
363
byte *str = ialloc_string(arg, "string token");
300
make_int(pref, (p[1] ^ 128) - 128);
301
s_end_inline(s, p + 1, rlimit);
305
if (!num_is_valid(num_format))
306
return_error(e_syntaxerror);
307
wanted = 1 + encoded_number_bytes(num_format);
308
if (rlimit - p < wanted) {
309
s_end_inline(s, p - 1, rlimit);
310
pstate->s_scan_type = scanning_none;
313
code = sdecode_number(p + 2, num_format, pref);
319
case BT_FLOAT_IEEE_MSB:
320
case BT_FLOAT_IEEE_LSB:
321
case BT_FLOAT_NATIVE:
322
code = sdecode_number(p + 1, num_format, pref);
327
r_set_type(pref, code);
330
return_error(e_syntaxerror);
334
s_end_inline(s, p + wanted, rlimit);
339
return_error(e_syntaxerror);
340
make_bool(pref, arg);
341
s_end_inline(s, p + 1, rlimit);
346
case BT_STRING_64K_MSB:
347
case BT_STRING_64K_LSB:
348
arg = sdecodeushort(p + 1, num_format);
351
if (s->foreign && rlimit - p >= arg) {
353
* Reference the string directly in the buffer. It is
354
* marked writable for consistency with the non-direct
355
* case, but since the "buffer" may be data compiled into
356
* the executable, it is probably actually read-only.
358
s_end_inline(s, p, rlimit);
359
make_const_string(pref, a_all | avm_foreign, arg, sbufptr(s));
363
byte *str = ialloc_string(arg, "string token");
366
return_error(e_VMerror);
367
s_end_inline(s, p, rlimit);
368
pstate->s_da.base = pstate->s_da.next = str;
369
pstate->s_da.limit = str + arg;
370
code = scan_bin_string_continue(i_ctx_p, pref, pstate);
371
if (code == scan_Refill || code < 0) {
372
pstate->s_da.is_dynamic = true;
373
make_null(&pbs->bin_array); /* clean up for GC */
374
pbs->cont = scan_bin_string_continue;
378
case BT_LITNAME_SYSTEM:
379
code = scan_bin_get_name(pstate, imemory, system_names_p, p[1],
382
case BT_EXECNAME_SYSTEM:
383
code = scan_bin_get_name(pstate, imemory, system_names_p, p[1],
386
case BT_LITNAME_USER:
387
code = scan_bin_get_name(pstate, imemory, user_names_p, p[1],
392
s_end_inline(s, p + 1, rlimit);
394
case BT_EXECNAME_USER:
395
code = scan_bin_get_name(pstate, imemory, user_names_p, p[1],
400
r_set_attrs(pref, a_executable);
401
s_end_inline(s, p + 1, rlimit);
405
if (!num_is_valid(num_format))
406
return_error(e_syntaxerror);
407
arg = sdecodeushort(p + 2, num_format);
408
code = ialloc_ref_array(&pbs->bin_array, a_all, arg,
409
"number array token");
412
pbs->num_format = num_format;
415
s_end_inline(s, p, rlimit);
416
code = scan_bin_num_array_continue(i_ctx_p, pref, pstate);
417
if (code == scan_Refill || code < 0) {
418
/* Make sure the array is clean for the GC. */
419
refset_null(pbs->bin_array.value.refs + pbs->index,
421
pbs->cont = scan_bin_num_array_continue;
366
return_error(e_VMerror);
367
s_end_inline(s, p, rlimit);
368
pstate->s_da.base = pstate->s_da.next = str;
369
pstate->s_da.limit = str + arg;
370
code = scan_bin_string_continue(i_ctx_p, pref, pstate);
371
if (code == scan_Refill || code < 0) {
372
pstate->s_da.is_dynamic = true;
373
make_null(&pbs->bin_array); /* clean up for GC */
374
pbs->cont = scan_bin_string_continue;
378
case BT_LITNAME_SYSTEM:
379
code = scan_bin_get_name(pstate, imemory, system_names_p, p[1],
382
case BT_EXECNAME_SYSTEM:
383
code = scan_bin_get_name(pstate, imemory, system_names_p, p[1],
386
case BT_LITNAME_USER:
387
code = scan_bin_get_name(pstate, imemory, user_names_p, p[1],
392
s_end_inline(s, p + 1, rlimit);
394
case BT_EXECNAME_USER:
395
code = scan_bin_get_name(pstate, imemory, user_names_p, p[1],
400
r_set_attrs(pref, a_executable);
401
s_end_inline(s, p + 1, rlimit);
405
if (!num_is_valid(num_format))
406
return_error(e_syntaxerror);
407
arg = sdecodeushort(p + 2, num_format);
408
code = ialloc_ref_array(&pbs->bin_array, a_all, arg,
409
"number array token");
412
pbs->num_format = num_format;
415
s_end_inline(s, p, rlimit);
416
code = scan_bin_num_array_continue(i_ctx_p, pref, pstate);
417
if (code == scan_Refill || code < 0) {
418
/* Make sure the array is clean for the GC. */
419
refset_null(pbs->bin_array.value.refs + pbs->index,
421
pbs->cont = scan_bin_num_array_continue;
425
425
return_error(e_syntaxerror);
532
532
pbs->cont = scan_bos_continue; /* in case of premature return */
533
533
s_begin_inline(s, p, rlimit);
534
534
for (; index < max_array_index; p += SIZEOF_BIN_SEQ_OBJ, index++) {
535
ref *op = abase + index;
537
int value, atype, attrs;
539
s_end_inline(s, p, rlimit); /* in case of error */
540
if (rlimit - p < SIZEOF_BIN_SEQ_OBJ) {
542
pbs->max_array_index = max_array_index;
543
pbs->min_string_index = min_string_index;
544
pstate->s_scan_type = scanning_binary;
547
if (p[2] != 0) { /* reserved, must be 0 */
548
scan_bos_error(pstate, "non-zero unused field");
549
return_error(e_syntaxerror);
551
attrs = (p[1] & 128 ? a_executable : 0);
553
* We always decode all 8 bytes of the object, so we can signal
554
* syntaxerror if any unused field is non-zero (per PLRM).
556
osize = sdecodeushort(p + 3, num_format);
557
value = sdecodeint32(p + 5, num_format);
558
switch (p[1] & 0x7f) {
560
if (osize | value) { /* unused */
561
scan_bos_error(pstate, "non-zero unused field");
562
return_error(e_syntaxerror);
566
case BS_TYPE_INTEGER:
567
if (osize) { /* unused */
568
scan_bos_error(pstate, "non-zero unused field");
569
return_error(e_syntaxerror);
576
if (osize != 0) { /* fixed-point number */
578
scan_bos_error(pstate, "invalid number format");
579
return_error(e_syntaxerror);
581
/* ldexp requires a signed 2nd argument.... */
582
vreal = (float)ldexp((double)value, -(int)osize);
584
code = sdecode_float(p + 5, num_format, &vreal);
586
scan_bos_error(pstate, "invalid real number");
590
make_real(op, vreal);
593
case BS_TYPE_BOOLEAN:
594
if (osize) { /* unused */
595
scan_bos_error(pstate, "non-zero unused field");
596
return_error(e_syntaxerror);
598
make_bool(op, value != 0);
604
/* For zero-length strings, the offset */
605
/* doesn't matter, and may be zero. */
606
make_empty_string(op, attrs);
609
if (value < max_array_index * SIZEOF_BIN_SEQ_OBJ ||
612
scan_bos_error(pstate, "invalid string offset");
613
return_error(e_syntaxerror);
615
if (value < min_string_index) {
616
/* We have to (re)allocate the strings. */
617
uint str_size = size - value;
620
if (pstate->s_da.is_dynamic)
621
sbase = scan_bos_resize(i_ctx_p, pstate, str_size,
624
sbase = ialloc_string(str_size,
627
return_error(e_VMerror);
628
pstate->s_da.is_dynamic = true;
629
pstate->s_da.base = pstate->s_da.next = sbase;
630
pstate->s_da.limit = sbase + str_size;
631
min_string_index = value;
633
make_string(op, attrs | icurrent_space, osize,
635
(value - min_string_index));
637
case BS_TYPE_EVAL_NAME:
638
attrs |= a_readonly; /* mark as executable for later */
643
code = scan_bin_get_name(pstate, imemory,
644
user_names_p, value, op,
648
code = scan_bin_get_name(pstate, imemory,
649
system_names_p, value, op,
654
r_set_attrs(op, attrs);
663
if (value + osize > min_string_index ||
664
value & (SIZEOF_BIN_SEQ_OBJ - 1)
666
scan_bos_error(pstate, "bad array offset");
667
return_error(e_syntaxerror);
670
uint aindex = value / SIZEOF_BIN_SEQ_OBJ;
673
max(max_array_index, aindex + osize);
674
make_tasv_new(op, atype,
675
attrs | a_all | icurrent_space,
676
osize, refs, abase + aindex);
679
case BS_TYPE_DICTIONARY: /* EXTENSION */
680
if ((osize & 1) != 0 && osize != 1)
681
return_error(e_syntaxerror);
682
atype = t_mixedarray; /* mark as dictionary */
685
if (osize | value) { /* unused */
686
scan_bos_error(pstate, "non-zero unused field");
687
return_error(e_syntaxerror);
692
scan_bos_error(pstate, "invalid object type");
693
return_error(e_syntaxerror);
535
ref *op = abase + index;
537
int value, atype, attrs;
539
s_end_inline(s, p, rlimit); /* in case of error */
540
if (rlimit - p < SIZEOF_BIN_SEQ_OBJ) {
542
pbs->max_array_index = max_array_index;
543
pbs->min_string_index = min_string_index;
544
pstate->s_scan_type = scanning_binary;
547
if (p[2] != 0) { /* reserved, must be 0 */
548
scan_bos_error(pstate, "non-zero unused field");
549
return_error(e_syntaxerror);
551
attrs = (p[1] & 128 ? a_executable : 0);
553
* We always decode all 8 bytes of the object, so we can signal
554
* syntaxerror if any unused field is non-zero (per PLRM).
556
osize = sdecodeushort(p + 3, num_format);
557
value = sdecodeint32(p + 5, num_format);
558
switch (p[1] & 0x7f) {
560
if (osize | value) { /* unused */
561
scan_bos_error(pstate, "non-zero unused field");
562
return_error(e_syntaxerror);
566
case BS_TYPE_INTEGER:
567
if (osize) { /* unused */
568
scan_bos_error(pstate, "non-zero unused field");
569
return_error(e_syntaxerror);
576
if (osize != 0) { /* fixed-point number */
578
scan_bos_error(pstate, "invalid number format");
579
return_error(e_syntaxerror);
581
/* ldexp requires a signed 2nd argument.... */
582
vreal = (float)ldexp((double)value, -(int)osize);
584
code = sdecode_float(p + 5, num_format, &vreal);
586
scan_bos_error(pstate, "invalid real number");
590
make_real(op, vreal);
593
case BS_TYPE_BOOLEAN:
594
if (osize) { /* unused */
595
scan_bos_error(pstate, "non-zero unused field");
596
return_error(e_syntaxerror);
598
make_bool(op, value != 0);
604
/* For zero-length strings, the offset */
605
/* doesn't matter, and may be zero. */
606
make_empty_string(op, attrs);
609
if (value < max_array_index * SIZEOF_BIN_SEQ_OBJ ||
612
scan_bos_error(pstate, "invalid string offset");
613
return_error(e_syntaxerror);
615
if (value < min_string_index) {
616
/* We have to (re)allocate the strings. */
617
uint str_size = size - value;
620
if (pstate->s_da.is_dynamic)
621
sbase = scan_bos_resize(i_ctx_p, pstate, str_size,
624
sbase = ialloc_string(str_size,
627
return_error(e_VMerror);
628
pstate->s_da.is_dynamic = true;
629
pstate->s_da.base = pstate->s_da.next = sbase;
630
pstate->s_da.limit = sbase + str_size;
631
min_string_index = value;
633
make_string(op, attrs | icurrent_space, osize,
635
(value - min_string_index));
637
case BS_TYPE_EVAL_NAME:
638
attrs |= a_readonly; /* mark as executable for later */
643
code = scan_bin_get_name(pstate, imemory,
644
user_names_p, value, op,
648
code = scan_bin_get_name(pstate, imemory,
649
system_names_p, value, op,
654
r_set_attrs(op, attrs);
663
if (value + osize > min_string_index ||
664
value & (SIZEOF_BIN_SEQ_OBJ - 1)
666
scan_bos_error(pstate, "bad array offset");
667
return_error(e_syntaxerror);
670
uint aindex = value / SIZEOF_BIN_SEQ_OBJ;
673
max(max_array_index, aindex + osize);
674
make_tasv_new(op, atype,
675
attrs | a_all | icurrent_space,
676
osize, refs, abase + aindex);
679
case BS_TYPE_DICTIONARY: /* EXTENSION */
680
if ((osize & 1) != 0 && osize != 1)
681
return_error(e_syntaxerror);
682
atype = t_mixedarray; /* mark as dictionary */
685
if (osize | value) { /* unused */
686
scan_bos_error(pstate, "non-zero unused field");
687
return_error(e_syntaxerror);
692
scan_bos_error(pstate, "invalid object type");
693
return_error(e_syntaxerror);
696
696
s_end_inline(s, p, rlimit);
697
697
/* Shorten the objects to remove the space that turned out */
698
698
/* to be used for strings. */
699
699
pbs->index = max_array_index;
700
700
iresize_ref_array(&pbs->bin_array, max_array_index,
701
"binary object sequence(objects)");
701
"binary object sequence(objects)");
702
702
code = scan_bos_string_continue(i_ctx_p, pref, pstate);
703
703
if (code == scan_Refill)
704
pbs->cont = scan_bos_string_continue;
704
pbs->cont = scan_bos_string_continue;
751
751
/* Fix up names. We must do this before creating dictionaries. */
753
753
for (op = pbs->bin_array.value.refs, i = r_size(&pbs->bin_array);
756
switch (r_type(op)) {
758
if (r_has_attr(op, a_write)) /* a real string */
760
/* This is actually a name; look it up now. */
762
uint attrs = r_type_attrs(op) & (a_read | a_executable);
764
code = name_ref(imemory, op->value.bytes, r_size(op), op, 1);
767
r_set_attrs(op, attrs);
771
if (r_has_attr(op, a_read)) { /* BS_TYPE_EVAL_NAME */
772
ref *defp = dict_find_name(op);
775
return_error(e_undefined);
776
store_check_space(space, defp);
777
ref_assign(op, defp);
780
case t_mixedarray: /* actually a dictionary */
756
switch (r_type(op)) {
758
if (r_has_attr(op, a_write)) /* a real string */
760
/* This is actually a name; look it up now. */
762
uint attrs = r_type_attrs(op) & (a_read | a_executable);
764
code = name_ref(imemory, op->value.bytes, r_size(op), op, 1);
767
r_set_attrs(op, attrs);
771
if (r_has_attr(op, a_read)) { /* BS_TYPE_EVAL_NAME */
772
ref *defp = dict_find_name(op);
775
return_error(e_undefined);
776
store_check_space(space, defp);
777
ref_assign(op, defp);
780
case t_mixedarray: /* actually a dictionary */
784
784
/* Create dictionaries, if any. */
788
for (op = pbs->bin_array.value.refs, i = r_size(&pbs->bin_array);
791
switch (r_type(op)) {
792
case t_mixedarray: /* actually a dictionary */
794
uint count = r_size(op);
788
for (op = pbs->bin_array.value.refs, i = r_size(&pbs->bin_array);
791
switch (r_type(op)) {
792
case t_mixedarray: /* actually a dictionary */
794
uint count = r_size(op);
798
/* Indirect reference. */
799
if (op->value.refs < op)
800
ref_assign(&rdict, op->value.refs);
806
code = dict_create(count >> 1, &rdict);
811
code = idict_put(&rdict,
812
&op->value.refs[count],
813
&op->value.refs[count + 1]);
818
r_set_attrs(&rdict, a_all);
819
r_copy_attrs(&rdict, a_executable, op);
820
ref_assign(op, &rdict);
798
/* Indirect reference. */
799
if (op->value.refs < op)
800
ref_assign(&rdict, op->value.refs);
806
code = dict_create(count >> 1, &rdict);
811
code = idict_put(&rdict,
812
&op->value.refs[count],
813
&op->value.refs[count + 1]);
818
r_set_attrs(&rdict, a_all);
819
r_copy_attrs(&rdict, a_executable, op);
820
ref_assign(op, &rdict);
826
826
/* If there were any forward indirect references, fix them up now. */
829
for (op = pbs->bin_array.value.refs, i = r_size(&pbs->bin_array);
832
if (r_has_type(op, t_mixedarray)) {
833
const ref *piref = op->value.const_refs;
829
for (op = pbs->bin_array.value.refs, i = r_size(&pbs->bin_array);
832
if (r_has_type(op, t_mixedarray)) {
833
const ref *piref = op->value.const_refs;
836
if (r_has_type(piref, t_mixedarray)) /* ref to indirect */
837
return_error(e_syntaxerror);
838
ref_assign(&rdict, piref);
839
r_copy_attrs(&rdict, a_executable, op);
840
ref_assign(op, &rdict);
836
if (r_has_type(piref, t_mixedarray)) /* ref to indirect */
837
return_error(e_syntaxerror);
838
ref_assign(&rdict, piref);
839
r_copy_attrs(&rdict, a_executable, op);
840
ref_assign(op, &rdict);
843
843
ref_assign(pref, &pbs->bin_array);
844
844
r_set_size(pref, pbs->top_size);
865
865
switch (r_type(obj)) {
868
break; /* always set all fields */
871
break; /* always set all fields */
873
type = BS_TYPE_INTEGER;
874
value = obj->value.intval;
878
if (sizeof(obj->value.realval) != sizeof(int)) {
879
/* The PLRM allocates exactly 4 bytes for reals. */
880
return_error(e_rangecheck);
882
value = *(const int *)&obj->value.realval;
868
break; /* always set all fields */
871
break; /* always set all fields */
873
type = BS_TYPE_INTEGER;
874
value = obj->value.intval;
878
if (sizeof(obj->value.realval) != sizeof(int)) {
879
/* The PLRM allocates exactly 4 bytes for reals. */
880
return_error(e_rangecheck);
882
value = *(const int *)&obj->value.realval;
883
883
#if !(ARCH_FLOATS_ARE_IEEE && BYTE_SWAP_IEEE_NATIVE_REALS)
885
/* Never byte-swap native reals -- use native byte order. */
886
format = 4 - ARCH_IS_BIG_ENDIAN;
885
/* Never byte-swap native reals -- use native byte order. */
886
format = 4 - ARCH_IS_BIG_ENDIAN;
891
type = BS_TYPE_BOOLEAN;
892
value = obj->value.boolval;
895
type = BS_TYPE_ARRAY;
898
case t_dictionary: /* EXTENSION */
899
type = BS_TYPE_DICTIONARY;
900
size = dict_length(obj) << 1;
901
aod:value = *ref_offset;
902
*ref_offset += size * SIZEOF_BIN_SEQ_OBJ;
905
type = BS_TYPE_STRING;
891
type = BS_TYPE_BOOLEAN;
892
value = obj->value.boolval;
895
type = BS_TYPE_ARRAY;
898
case t_dictionary: /* EXTENSION */
899
type = BS_TYPE_DICTIONARY;
900
size = dict_length(obj) << 1;
901
aod:value = *ref_offset;
902
*ref_offset += size * SIZEOF_BIN_SEQ_OBJ;
905
type = BS_TYPE_STRING;
908
value = *char_offset;
909
*char_offset += size;
913
name_string_ref(imemory, obj, &nstr);
914
r_copy_attrs(&nstr, a_executable, obj);
918
return_error(e_rangecheck);
908
value = *char_offset;
909
*char_offset += size;
913
name_string_ref(imemory, obj, &nstr);
914
r_copy_attrs(&nstr, a_executable, obj);
918
return_error(e_rangecheck);
921
byte s0 = (byte) size, s1 = (byte) (size >> 8);
922
byte v0 = (byte) value, v1 = (byte) (value >> 8),
923
v2 = (byte) (value >> 16), v3 = (byte) (value >> 24);
921
byte s0 = (byte) size, s1 = (byte) (size >> 8);
922
byte v0 = (byte) value, v1 = (byte) (value >> 8),
923
v2 = (byte) (value >> 16), v3 = (byte) (value >> 24);
926
/* Store big-endian */
927
str[2] = s1, str[3] = s0;
928
str[4] = v3, str[5] = v2, str[6] = v1, str[7] = v0;
930
/* Store little-endian */
931
str[2] = s0, str[3] = s1;
932
str[4] = v0, str[5] = v1, str[6] = v2, str[7] = v3;
926
/* Store big-endian */
927
str[2] = s1, str[3] = s0;
928
str[4] = v3, str[5] = v2, str[6] = v1, str[7] = v0;
930
/* Store little-endian */
931
str[2] = s0, str[3] = s1;
932
str[4] = v0, str[5] = v1, str[6] = v2, str[7] = v3;
935
935
if (r_has_attr(obj, a_executable))
936
type += BS_EXECUTABLE;
936
type += BS_EXECUTABLE;
937
937
str[0] = (byte) type;